From f10aa7dddc0620e0bcaaf9cf895f9986424294a4 Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Fri, 19 May 2023 12:56:09 +0000
Subject: [PATCH 01/19] Simplify pre-order algorithm.

---
 compiler/rustc_borrowck/src/dataflow.rs | 94 +++++++++++--------------
 1 file changed, 43 insertions(+), 51 deletions(-)

diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 2daa82aef3957..5798d67d1ba99 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -125,15 +125,9 @@ pub struct Borrows<'a, 'tcx> {
     borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
 }
 
-struct StackEntry {
-    bb: mir::BasicBlock,
-    lo: usize,
-    hi: usize,
-}
-
 struct OutOfScopePrecomputer<'a, 'tcx> {
     visited: BitSet<mir::BasicBlock>,
-    visit_stack: Vec<StackEntry>,
+    visit_stack: Vec<mir::BasicBlock>,
     body: &'a Body<'tcx>,
     regioncx: &'a RegionInferenceContext<'tcx>,
     borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
@@ -158,29 +152,50 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
         borrow_region: RegionVid,
         first_location: Location,
     ) {
-        // We visit one BB at a time. The complication is that we may start in the
-        // middle of the first BB visited (the one containing `first_location`), in which
-        // case we may have to later on process the first part of that BB if there
-        // is a path back to its start.
-
-        // For visited BBs, we record the index of the first statement processed.
-        // (In fully processed BBs this index is 0.) Note also that we add BBs to
-        // `visited` once they are added to `stack`, before they are actually
-        // processed, because this avoids the need to look them up again on
-        // completion.
-        self.visited.insert(first_location.block);
-
         let first_block = first_location.block;
-        let mut first_lo = first_location.statement_index;
-        let first_hi = self.body[first_block].statements.len();
+        let first_bb_data = &self.body.basic_blocks[first_block];
+
+        // This is the first block, we only want to visit it from the creation of the borrow at
+        // `first_location`.
+        let first_lo = first_location.statement_index;
+        let first_hi = first_bb_data.statements.len();
+
+        if let Some(kill_stmt) = self.regioncx.first_non_contained_inclusive(
+            borrow_region,
+            first_block,
+            first_lo,
+            first_hi,
+        ) {
+            let kill_location = Location { block: first_block, statement_index: kill_stmt };
+            // If region does not contain a point at the location, then add to list and skip
+            // successor locations.
+            debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
+            self.borrows_out_of_scope_at_location
+                .entry(kill_location)
+                .or_default()
+                .push(borrow_index);
+
+            // The borrow is already dead, there is no need to visit other blocks.
+            return;
+        }
 
-        self.visit_stack.push(StackEntry { bb: first_block, lo: first_lo, hi: first_hi });
+        // The borrow is not dead. Add successor BBs to the work list, if necessary.
+        for succ_bb in first_bb_data.terminator().successors() {
+            if self.visited.insert(succ_bb) {
+                self.visit_stack.push(succ_bb);
+            }
+        }
 
-        'preorder: while let Some(StackEntry { bb, lo, hi }) = self.visit_stack.pop() {
+        // We may end up visiting `first_block` again. This is not an issue: we know at this point
+        // that it does not kill the borrow in the `first_lo..=first_hi` range, so checking the
+        // `0..first_lo` range and the `0..first_hi` range give the same result.
+        while let Some(block) = self.visit_stack.pop() {
+            let bb_data = &self.body[block];
+            let num_stmts = bb_data.statements.len();
             if let Some(kill_stmt) =
-                self.regioncx.first_non_contained_inclusive(borrow_region, bb, lo, hi)
+                self.regioncx.first_non_contained_inclusive(borrow_region, block, 0, num_stmts)
             {
-                let kill_location = Location { block: bb, statement_index: kill_stmt };
+                let kill_location = Location { block, statement_index: kill_stmt };
                 // If region does not contain a point at the location, then add to list and skip
                 // successor locations.
                 debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
@@ -188,38 +203,15 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
                     .entry(kill_location)
                     .or_default()
                     .push(borrow_index);
-                continue 'preorder;
-            }
 
-            // If we process the first part of the first basic block (i.e. we encounter that block
-            // for the second time), we no longer have to visit its successors again.
-            if bb == first_block && hi != first_hi {
+                // We killed the borrow, so we do not visit this block's successors.
                 continue;
             }
 
             // Add successor BBs to the work list, if necessary.
-            let bb_data = &self.body[bb];
-            debug_assert!(hi == bb_data.statements.len());
             for succ_bb in bb_data.terminator().successors() {
-                if !self.visited.insert(succ_bb) {
-                    if succ_bb == first_block && first_lo > 0 {
-                        // `succ_bb` has been seen before. If it wasn't
-                        // fully processed, add its first part to `stack`
-                        // for processing.
-                        self.visit_stack.push(StackEntry { bb: succ_bb, lo: 0, hi: first_lo - 1 });
-
-                        // And update this entry with 0, to represent the
-                        // whole BB being processed.
-                        first_lo = 0;
-                    }
-                } else {
-                    // succ_bb hasn't been seen before. Add it to
-                    // `stack` for processing.
-                    self.visit_stack.push(StackEntry {
-                        bb: succ_bb,
-                        lo: 0,
-                        hi: self.body[succ_bb].statements.len(),
-                    });
+                if self.visited.insert(succ_bb) {
+                    self.visit_stack.push(succ_bb);
                 }
             }
         }

From db235a07f79a34fe9e40bb122d6ae78f05bc2623 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 20 Jun 2023 20:00:39 +0000
Subject: [PATCH 02/19] Remove unnecessary call to select_from_obligation

The only regression is one ambiguity in the new trait solver, having to
do with two param-env candidates that may apply. I think this is fine,
since the error message already kinda sucks.
---
 .../src/traits/error_reporting/mod.rs         | 83 ++++++++-----------
 ...tion-param-candidates-are-ambiguous.stderr |  1 +
 2 files changed, 35 insertions(+), 49 deletions(-)

diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 398ec28a42638..75aee0670a258 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -5,7 +5,7 @@ pub mod suggestions;
 use super::{
     FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
     ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
-    PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
+    PredicateObligation, SelectionError, TraitNotObjectSafe,
 };
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -2269,55 +2269,40 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     )
                 };
 
-                let obligation = obligation.with(self.tcx, trait_ref);
-                let mut selcx = SelectionContext::new(&self);
-                match selcx.select_from_obligation(&obligation) {
-                    Ok(None) => {
-                        let ambiguities =
-                            ambiguity::recompute_applicable_impls(self.infcx, &obligation);
-                        let has_non_region_infer = trait_ref
-                            .skip_binder()
-                            .substs
-                            .types()
-                            .any(|t| !t.is_ty_or_numeric_infer());
-                        // It doesn't make sense to talk about applicable impls if there are more
-                        // than a handful of them.
-                        if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
-                            if self.tainted_by_errors().is_some() && subst.is_none() {
-                                // If `subst.is_none()`, then this is probably two param-env
-                                // candidates or impl candidates that are equal modulo lifetimes.
-                                // Therefore, if we've already emitted an error, just skip this
-                                // one, since it's not particularly actionable.
-                                err.cancel();
-                                return;
-                            }
-                            self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
-                        } else {
-                            if self.tainted_by_errors().is_some() {
-                                err.cancel();
-                                return;
-                            }
-                            err.note(format!("cannot satisfy `{}`", predicate));
-                            let impl_candidates = self.find_similar_impl_candidates(
-                                predicate.to_opt_poly_trait_pred().unwrap(),
-                            );
-                            if impl_candidates.len() < 10 {
-                                self.report_similar_impl_candidates(
-                                    impl_candidates.as_slice(),
-                                    trait_ref,
-                                    obligation.cause.body_id,
-                                    &mut err,
-                                    false,
-                                );
-                            }
-                        }
+                let ambiguities = ambiguity::recompute_applicable_impls(
+                    self.infcx,
+                    &obligation.with(self.tcx, trait_ref),
+                );
+                let has_non_region_infer =
+                    trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer());
+                // It doesn't make sense to talk about applicable impls if there are more
+                // than a handful of them.
+                if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
+                    if self.tainted_by_errors().is_some() && subst.is_none() {
+                        // If `subst.is_none()`, then this is probably two param-env
+                        // candidates or impl candidates that are equal modulo lifetimes.
+                        // Therefore, if we've already emitted an error, just skip this
+                        // one, since it's not particularly actionable.
+                        err.cancel();
+                        return;
                     }
-                    _ => {
-                        if self.tainted_by_errors().is_some() {
-                            err.cancel();
-                            return;
-                        }
-                        err.note(format!("cannot satisfy `{}`", predicate));
+                    self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
+                } else {
+                    if self.tainted_by_errors().is_some() {
+                        err.cancel();
+                        return;
+                    }
+                    err.note(format!("cannot satisfy `{}`", predicate));
+                    let impl_candidates = self
+                        .find_similar_impl_candidates(predicate.to_opt_poly_trait_pred().unwrap());
+                    if impl_candidates.len() < 10 {
+                        self.report_similar_impl_candidates(
+                            impl_candidates.as_slice(),
+                            trait_ref,
+                            obligation.cause.body_id,
+                            &mut err,
+                            false,
+                        );
                     }
                 }
 
diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
index fa5e780ee5e8b..83a0452b088d2 100644
--- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
+++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr
@@ -5,6 +5,7 @@ LL |     needs_bar::<T>();
    |     ^^^^^^^^^^^^^^
    |
    = note: cannot satisfy `T: Bar`
+   = help: the trait `Bar` is implemented for `T`
 note: required by a bound in `needs_bar`
   --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
    |

From 42571c4847692edc050288372a107e51ab4a9ce4 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 20 Jun 2023 21:27:43 +0000
Subject: [PATCH 03/19] yeet ImplSource::TraitAlias too

---
 compiler/rustc_middle/src/traits/mod.rs       | 19 -------------------
 .../src/traits/structural_impls.rs            | 12 ------------
 .../src/traits/project.rs                     |  4 +---
 .../src/traits/select/confirmation.rs         | 14 ++++++--------
 compiler/rustc_ty_utils/src/instance.rs       |  4 +---
 5 files changed, 8 insertions(+), 45 deletions(-)

diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index f03802049707c..f2bda4adf48e7 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -660,9 +660,6 @@ pub enum ImplSource<'tcx, N> {
 
     /// ImplSource for trait upcasting coercion
     TraitUpcasting(ImplSourceTraitUpcastingData<N>),
-
-    /// ImplSource for a trait alias.
-    TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
 }
 
 impl<'tcx, N> ImplSource<'tcx, N> {
@@ -671,7 +668,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             ImplSource::UserDefined(i) => i.nested,
             ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
             ImplSource::Object(d) => d.nested,
-            ImplSource::TraitAlias(d) => d.nested,
             ImplSource::TraitUpcasting(d) => d.nested,
         }
     }
@@ -681,7 +677,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             ImplSource::UserDefined(i) => &i.nested,
             ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
             ImplSource::Object(d) => &d.nested,
-            ImplSource::TraitAlias(d) => &d.nested,
             ImplSource::TraitUpcasting(d) => &d.nested,
         }
     }
@@ -691,7 +686,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             ImplSource::UserDefined(i) => &mut i.nested,
             ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
             ImplSource::Object(d) => &mut d.nested,
-            ImplSource::TraitAlias(d) => &mut d.nested,
             ImplSource::TraitUpcasting(d) => &mut d.nested,
         }
     }
@@ -713,11 +707,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
                 vtable_base: o.vtable_base,
                 nested: o.nested.into_iter().map(f).collect(),
             }),
-            ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
-                alias_def_id: d.alias_def_id,
-                substs: d.substs,
-                nested: d.nested.into_iter().map(f).collect(),
-            }),
             ImplSource::TraitUpcasting(d) => {
                 ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
                     vtable_vptr_slot: d.vtable_vptr_slot,
@@ -773,14 +762,6 @@ pub struct ImplSourceObjectData<N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceTraitAliasData<'tcx, N> {
-    pub alias_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    pub nested: Vec<N>,
-}
-
 #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
 pub enum ObjectSafetyViolation {
     /// `Self: Sized` declared on the trait.
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index ac02d6ed62f2e..1a89560188a91 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -17,8 +17,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
                 write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
             }
 
-            super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
-
             super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
         }
     }
@@ -53,13 +51,3 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
         )
     }
 }
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceTraitAliasData(alias_def_id={:?}, substs={:?}, nested={:?})",
-            self.alias_def_id, self.substs, self.nested
-        )
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index eb4cb88fb0b1e..bdffb9235e5b2 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1721,7 +1721,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
         };
 
         let eligible = match &impl_source {
-            super::ImplSource::TraitAlias(_) => true,
             super::ImplSource::UserDefined(impl_data) => {
                 // We have to be careful when projecting out of an
                 // impl because of specialization. If we are not in
@@ -2013,8 +2012,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
         }
         super::ImplSource::Object(_)
         | super::ImplSource::Param(..)
-        | super::ImplSource::TraitUpcasting(_)
-        | super::ImplSource::TraitAlias(..) => {
+        | super::ImplSource::TraitUpcasting(_) => {
             // we don't create Select candidates with this kind of resolution
             span_bug!(
                 obligation.cause.span,
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 3c356978d5ca8..88941a7575534 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -27,10 +27,9 @@ use crate::traits::vtable::{
 };
 use crate::traits::{
     BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
-    ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData,
-    ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
-    OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
-    TraitNotObjectSafe, TraitObligation, Unimplemented,
+    ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
+    Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
+    SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
 };
 
 use super::BuiltinImplConditions;
@@ -105,7 +104,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             TraitAliasCandidate => {
                 let data = self.confirm_trait_alias_candidate(obligation);
-                ImplSource::TraitAlias(data)
+                ImplSource::Builtin(data)
             }
 
             BuiltinObjectCandidate => {
@@ -721,10 +720,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn confirm_trait_alias_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> {
+    ) -> Vec<PredicateObligation<'tcx>> {
         debug!(?obligation, "confirm_trait_alias_candidate");
 
-        let alias_def_id = obligation.predicate.def_id();
         let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
         let trait_ref = predicate.trait_ref;
         let trait_def_id = trait_ref.def_id;
@@ -741,7 +739,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
 
-        ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations }
+        trait_obligations
     }
 
     fn confirm_generator_candidate(
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 45b1075b6023a..2d75862014d0b 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -293,9 +293,7 @@ fn resolve_associated_item<'tcx>(
                 None
             }
         }
-        traits::ImplSource::Param(..)
-        | traits::ImplSource::TraitAlias(..)
-        | traits::ImplSource::TraitUpcasting(_) => None,
+        traits::ImplSource::Param(..) | traits::ImplSource::TraitUpcasting(_) => None,
     })
 }
 

From 7d0a5c31f5b3b4b1dc47ce51898be8895c9f4637 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 20 Jun 2023 21:48:05 +0000
Subject: [PATCH 04/19] yeet upcast_trait_def_id from ImplSourceObjectData

---
 compiler/rustc_middle/src/traits/mod.rs                     | 4 ----
 compiler/rustc_middle/src/traits/structural_impls.rs        | 4 ++--
 .../rustc_trait_selection/src/traits/select/confirmation.rs | 6 +-----
 compiler/rustc_trait_selection/src/traits/util.rs           | 2 +-
 4 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index f2bda4adf48e7..a333fbbb50671 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -703,7 +703,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
             ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
             ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
-                upcast_trait_def_id: o.upcast_trait_def_id,
                 vtable_base: o.vtable_base,
                 nested: o.nested.into_iter().map(f).collect(),
             }),
@@ -750,9 +749,6 @@ pub struct ImplSourceTraitUpcastingData<N> {
 #[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct ImplSourceObjectData<N> {
-    /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
-    pub upcast_trait_def_id: DefId,
-
     /// The vtable is formed by concatenating together the method lists of
     /// the base object trait and all supertraits, pointers to supertrait vtable will
     /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 1a89560188a91..a703e3c956228 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -46,8 +46,8 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
-            "ImplSourceObjectData(upcast={:?}, vtable_base={}, nested={:?})",
-            self.upcast_trait_def_id, self.vtable_base, self.nested
+            "ImplSourceObjectData(vtable_base={}, nested={:?})",
+            self.vtable_base, self.nested
         )
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 88941a7575534..bf485ee7b53ae 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -651,11 +651,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
         );
 
-        Ok(ImplSourceObjectData {
-            upcast_trait_def_id: upcast_trait_ref.def_id(),
-            vtable_base,
-            nested,
-        })
+        Ok(ImplSourceObjectData { vtable_base, nested })
     }
 
     fn confirm_fn_pointer_candidate(
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 906c357e8ca7e..4dc2f26a8ed17 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -248,7 +248,7 @@ pub fn get_vtable_index_of_object_method<'tcx, N>(
 ) -> Option<usize> {
     // Count number of methods preceding the one we are selecting and
     // add them to the total offset.
-    tcx.own_existential_vtable_entries(object.upcast_trait_def_id)
+    tcx.own_existential_vtable_entries(tcx.parent(method_def_id))
         .iter()
         .copied()
         .position(|def_id| def_id == method_def_id)

From dc76991d2fa6448bfc5333d22f5d27c26b646d49 Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Sun, 14 May 2023 17:38:41 -0400
Subject: [PATCH 05/19] Remove `LineColumn`, `Span::start`, `Span::end`

---
 .../rustc_expand/src/proc_macro_server.rs     | 13 +----
 library/proc_macro/src/bridge/mod.rs          |  6 +--
 library/proc_macro/src/lib.rs                 | 51 -------------------
 .../crates/proc-macro-srv/src/server.rs       |  8 ---
 4 files changed, 2 insertions(+), 76 deletions(-)

diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 891e84a2f3071..3dd317405dd14 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -2,7 +2,7 @@ use crate::base::ExtCtxt;
 use pm::bridge::{
     server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
 };
-use pm::{Delimiter, Level, LineColumn};
+use pm::{Delimiter, Level};
 use rustc_ast as ast;
 use rustc_ast::token;
 use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
@@ -648,17 +648,6 @@ impl server::Span for Rustc<'_, '_> {
 
         Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
     }
-
-    fn start(&mut self, span: Self::Span) -> LineColumn {
-        let loc = self.sess().source_map().lookup_char_pos(span.lo());
-        LineColumn { line: loc.line, column: loc.col.to_usize() }
-    }
-
-    fn end(&mut self, span: Self::Span) -> LineColumn {
-        let loc = self.sess().source_map().lookup_char_pos(span.hi());
-        LineColumn { line: loc.line, column: loc.col.to_usize() }
-    }
-
     fn before(&mut self, span: Self::Span) -> Self::Span {
         span.shrink_to_lo()
     }
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index caecda1bc63fd..5c8e35590d4be 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -8,7 +8,7 @@
 
 #![deny(unsafe_code)]
 
-use crate::{Delimiter, Level, LineColumn, Spacing};
+use crate::{Delimiter, Level, Spacing};
 use std::fmt;
 use std::hash::Hash;
 use std::marker;
@@ -95,8 +95,6 @@ macro_rules! with_api {
                 fn parent($self: $S::Span) -> Option<$S::Span>;
                 fn source($self: $S::Span) -> $S::Span;
                 fn byte_range($self: $S::Span) -> Range<usize>;
-                fn start($self: $S::Span) -> LineColumn;
-                fn end($self: $S::Span) -> LineColumn;
                 fn before($self: $S::Span) -> $S::Span;
                 fn after($self: $S::Span) -> $S::Span;
                 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
@@ -299,7 +297,6 @@ mark_noop! {
     Delimiter,
     LitKind,
     Level,
-    LineColumn,
     Spacing,
 }
 
@@ -319,7 +316,6 @@ rpc_encode_decode!(
         Help,
     }
 );
-rpc_encode_decode!(struct LineColumn { line, column });
 rpc_encode_decode!(
     enum Spacing {
         Alone,
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index c64665b6ae0e8..d23becfed9fde 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -43,7 +43,6 @@ mod diagnostic;
 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
-use std::cmp::Ordering;
 use std::ops::{Range, RangeBounds};
 use std::path::PathBuf;
 use std::str::FromStr;
@@ -494,18 +493,6 @@ impl Span {
         self.0.byte_range()
     }
 
-    /// Gets the starting line/column in the source file for this span.
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
-    pub fn start(&self) -> LineColumn {
-        self.0.start().add_1_to_column()
-    }
-
-    /// Gets the ending line/column in the source file for this span.
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
-    pub fn end(&self) -> LineColumn {
-        self.0.end().add_1_to_column()
-    }
-
     /// Creates an empty span pointing to directly before this span.
     #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
     pub fn before(&self) -> Span {
@@ -586,44 +573,6 @@ impl fmt::Debug for Span {
     }
 }
 
-/// A line-column pair representing the start or end of a `Span`.
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct LineColumn {
-    /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
-    pub line: usize,
-    /// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
-    /// file on which the span starts or ends (inclusive).
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
-    pub column: usize,
-}
-
-impl LineColumn {
-    fn add_1_to_column(self) -> Self {
-        LineColumn { line: self.line, column: self.column + 1 }
-    }
-}
-
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl !Send for LineColumn {}
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl !Sync for LineColumn {}
-
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl Ord for LineColumn {
-    fn cmp(&self, other: &Self) -> Ordering {
-        self.line.cmp(&other.line).then(self.column.cmp(&other.column))
-    }
-}
-
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl PartialOrd for LineColumn {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
 /// The source file of a given `Span`.
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 #[derive(Clone)]
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
index 6fd8de59342c0..999e78aa56bf2 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
@@ -304,14 +304,6 @@ impl server::Span for RustAnalyzer {
         // FIXME handle span
         Range { start: 0, end: 0 }
     }
-    fn start(&mut self, _span: Self::Span) -> LineColumn {
-        // FIXME handle span
-        LineColumn { line: 0, column: 0 }
-    }
-    fn end(&mut self, _span: Self::Span) -> LineColumn {
-        // FIXME handle span
-        LineColumn { line: 0, column: 0 }
-    }
     fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
         // Just return the first span again, because some macros will unwrap the result.
         Some(first)

From 87ec0738ab6fd62408c3058694c413daeb40630b Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Sun, 14 May 2023 18:11:27 -0400
Subject: [PATCH 06/19] =?UTF-8?q?`Span::{before,=20after}`=20=E2=86=92=20`?=
 =?UTF-8?q?Span::{start,=20end}`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 compiler/rustc_expand/src/proc_macro_server.rs            | 4 ++--
 library/proc_macro/src/bridge/mod.rs                      | 4 ++--
 library/proc_macro/src/lib.rs                             | 8 ++++----
 .../rust-analyzer/crates/proc-macro-srv/src/server.rs     | 4 ++--
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 3dd317405dd14..9400c501aa58b 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -648,11 +648,11 @@ impl server::Span for Rustc<'_, '_> {
 
         Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
     }
-    fn before(&mut self, span: Self::Span) -> Self::Span {
+    fn start(&mut self, span: Self::Span) -> Self::Span {
         span.shrink_to_lo()
     }
 
-    fn after(&mut self, span: Self::Span) -> Self::Span {
+    fn end(&mut self, span: Self::Span) -> Self::Span {
         span.shrink_to_hi()
     }
 
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 5c8e35590d4be..c7c7e974ae92b 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -95,8 +95,8 @@ macro_rules! with_api {
                 fn parent($self: $S::Span) -> Option<$S::Span>;
                 fn source($self: $S::Span) -> $S::Span;
                 fn byte_range($self: $S::Span) -> Range<usize>;
-                fn before($self: $S::Span) -> $S::Span;
-                fn after($self: $S::Span) -> $S::Span;
+                fn start($self: $S::Span) -> $S::Span;
+                fn end($self: $S::Span) -> $S::Span;
                 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
                 fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
                 fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index d23becfed9fde..89b5aef1bcde1 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -495,14 +495,14 @@ impl Span {
 
     /// Creates an empty span pointing to directly before this span.
     #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
-    pub fn before(&self) -> Span {
-        Span(self.0.before())
+    pub fn start(&self) -> Span {
+        Span(self.0.start())
     }
 
     /// Creates an empty span pointing to directly after this span.
     #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
-    pub fn after(&self) -> Span {
-        Span(self.0.after())
+    pub fn end(&self) -> Span {
+        Span(self.0.end())
     }
 
     /// Creates a new span encompassing `self` and `other`.
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
index 999e78aa56bf2..410f07f9b8440 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
@@ -322,11 +322,11 @@ impl server::Span for RustAnalyzer {
         tt::TokenId::unspecified()
     }
 
-    fn after(&mut self, _self_: Self::Span) -> Self::Span {
+    fn end(&mut self, _self_: Self::Span) -> Self::Span {
         tt::TokenId::unspecified()
     }
 
-    fn before(&mut self, _self_: Self::Span) -> Self::Span {
+    fn start(&mut self, _self_: Self::Span) -> Self::Span {
         tt::TokenId::unspecified()
     }
 }

From a1cd8c3a2819586159dfb33559777959f087f028 Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Sun, 14 May 2023 18:30:18 -0400
Subject: [PATCH 07/19] Add `Span::{line, column}`

---
 compiler/rustc_expand/src/proc_macro_server.rs   | 10 ++++++++++
 library/proc_macro/src/bridge/mod.rs             |  2 ++
 library/proc_macro/src/lib.rs                    | 16 ++++++++++++++++
 .../crates/proc-macro-srv/src/server.rs          | 10 ++++++++++
 4 files changed, 38 insertions(+)

diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 9400c501aa58b..ecd2315112a68 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -656,6 +656,16 @@ impl server::Span for Rustc<'_, '_> {
         span.shrink_to_hi()
     }
 
+    fn line(&mut self, span: Self::Span) -> usize {
+        let loc = self.sess().source_map().lookup_char_pos(span.lo());
+        loc.line
+    }
+
+    fn column(&mut self, span: Self::Span) -> usize {
+        let loc = self.sess().source_map().lookup_char_pos(span.lo());
+        loc.col.to_usize() + 1
+    }
+
     fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
         let self_loc = self.sess().source_map().lookup_char_pos(first.lo());
         let other_loc = self.sess().source_map().lookup_char_pos(second.lo());
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index c7c7e974ae92b..86ce5d9c6d5fe 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -97,6 +97,8 @@ macro_rules! with_api {
                 fn byte_range($self: $S::Span) -> Range<usize>;
                 fn start($self: $S::Span) -> $S::Span;
                 fn end($self: $S::Span) -> $S::Span;
+                fn line($self: $S::Span) -> usize;
+                fn column($self: $S::Span) -> usize;
                 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
                 fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
                 fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 89b5aef1bcde1..cb8b7ec70e0f5 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -505,6 +505,22 @@ impl Span {
         Span(self.0.end())
     }
 
+    /// The one-indexed line of the source file where the span starts.
+    ///
+    /// To obtain the line of the span's end, use `span.end().line()`.
+    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    pub fn line(&self) -> usize {
+        self.0.line()
+    }
+
+    /// The one-indexed column of the source file where the span starts.
+    ///
+    /// To obtain the column of the span's end, use `span.end().column()`.
+    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    pub fn column(&self) -> usize {
+        self.0.column()
+    }
+
     /// Creates a new span encompassing `self` and `other`.
     ///
     /// Returns `None` if `self` and `other` are from different files.
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
index 410f07f9b8440..e67f1e798e85a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
@@ -329,6 +329,16 @@ impl server::Span for RustAnalyzer {
     fn start(&mut self, _self_: Self::Span) -> Self::Span {
         tt::TokenId::unspecified()
     }
+
+    fn line(&mut self, _span: Self::Span) -> usize {
+        // FIXME handle line
+        0
+    }
+
+    fn column(&mut self, _span: Self::Span) -> usize {
+        // FIXME handle column
+        0
+    }
 }
 
 impl server::Symbol for RustAnalyzer {

From 8dc3b8559c147aa8eab9c34db46e3427e0c4e25b Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Sun, 14 May 2023 18:56:11 -0400
Subject: [PATCH 08/19] Fix tests

---
 tests/ui/macros/auxiliary/proc_macro_sequence.rs   |  5 -----
 tests/ui/macros/same-sequence-span.stderr          |  7 +++----
 tests/ui/proc-macro/auxiliary/api/cmp.rs           | 11 +----------
 tests/ui/proc-macro/auxiliary/assert-span-pos.rs   |  5 ++---
 tests/ui/proc-macro/auxiliary/macro-only-syntax.rs |  4 ++--
 5 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/tests/ui/macros/auxiliary/proc_macro_sequence.rs b/tests/ui/macros/auxiliary/proc_macro_sequence.rs
index 1331480d835a4..2f69cbc945080 100644
--- a/tests/ui/macros/auxiliary/proc_macro_sequence.rs
+++ b/tests/ui/macros/auxiliary/proc_macro_sequence.rs
@@ -8,11 +8,6 @@ extern crate proc_macro;
 
 use proc_macro::{quote, Span, TokenStream, TokenTree};
 
-fn assert_same_span(a: Span, b: Span) {
-    assert_eq!(a.start(), b.start());
-    assert_eq!(a.end(), b.end());
-}
-
 // This macro generates a macro with the same macro definition as `manual_foo` in
 // `same-sequence-span.rs` but with the same span for all sequences.
 #[proc_macro]
diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr
index bdd191e8ed6eb..3242a32e2f4dd 100644
--- a/tests/ui/macros/same-sequence-span.stderr
+++ b/tests/ui/macros/same-sequence-span.stderr
@@ -17,15 +17,14 @@ LL |                $(= $z:tt)*
 error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
   --> $DIR/same-sequence-span.rs:19:1
    |
+LL | | }
+   | |_________________________________^ not allowed after `expr` fragments
+LL |
 LL |   proc_macro_sequence::make_foo!();
    |   ^-------------------------------
    |   |
    |  _in this macro invocation
    | |
-LL | |
-LL | |
-LL | | fn main() {}
-   | |_________________________________^ not allowed after `expr` fragments
    |
    = note: allowed there are: `=>`, `,` or `;`
    = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/proc-macro/auxiliary/api/cmp.rs b/tests/ui/proc-macro/auxiliary/api/cmp.rs
index 5784a6e5d94db..ec3e637acab78 100644
--- a/tests/ui/proc-macro/auxiliary/api/cmp.rs
+++ b/tests/ui/proc-macro/auxiliary/api/cmp.rs
@@ -1,18 +1,9 @@
-use proc_macro::{LineColumn, Punct, Spacing};
+use proc_macro::{Punct, Spacing};
 
 pub fn test() {
-    test_line_column_ord();
     test_punct_eq();
 }
 
-fn test_line_column_ord() {
-    let line0_column0 = LineColumn { line: 0, column: 0 };
-    let line0_column1 = LineColumn { line: 0, column: 1 };
-    let line1_column0 = LineColumn { line: 1, column: 0 };
-    assert!(line0_column0 < line0_column1);
-    assert!(line0_column1 < line1_column0);
-}
-
 fn test_punct_eq() {
     let colon_alone = Punct::new(':', Spacing::Alone);
     assert_eq!(colon_alone, ':');
diff --git a/tests/ui/proc-macro/auxiliary/assert-span-pos.rs b/tests/ui/proc-macro/auxiliary/assert-span-pos.rs
index 455c5c7c380af..8126470ece9d3 100644
--- a/tests/ui/proc-macro/auxiliary/assert-span-pos.rs
+++ b/tests/ui/proc-macro/auxiliary/assert-span-pos.rs
@@ -26,10 +26,9 @@ pub fn assert_span_pos(input: TokenStream) -> TokenStream {
     let line: usize = str1.parse().unwrap();
     let col: usize = str2.parse().unwrap();
 
-    let sp1s = sp1.start();
-    if (line, col) != (sp1s.line, sp1s.column) {
+    if (line, col) != (sp1.line(), sp1.column()) {
         let msg = format!("line/column mismatch: ({}, {}) != ({}, {})", line, col,
-            sp1s.line, sp1s.column);
+            sp1.line(), sp1.column());
         sp1.error(msg).emit();
     }
 
diff --git a/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs b/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
index c72306c3d50b3..faa8cfdb5ab4d 100644
--- a/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
+++ b/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
@@ -10,7 +10,7 @@
 // lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081).
 
 #![crate_type = "proc-macro"]
-#![feature(proc_macro_span)]
+#![feature(proc_macro_span, proc_macro_span_shrink)]
 
 extern crate proc_macro;
 use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree};
@@ -81,7 +81,7 @@ fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {
 
 fn check_useful_span(token: TokenTree, expected_filename: &str) {
     let span = token.span();
-    assert!(span.start().column < span.end().column);
+    assert!(span.column() < span.end().column());
 
     let source_path = span.source_file().path();
     let filename = source_path.components().last().unwrap();

From cd1c1b1a9f0f1c67e3ea23e691ce082294b9b026 Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Mon, 15 May 2023 02:03:30 -0700
Subject: [PATCH 09/19] Update to proc-macro2 1.0.57 to unblock proc_macro_span
 changes

---
 Cargo.lock | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 3d0f9e8844e06..9ea75799da137 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2649,9 +2649,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16"
 dependencies = [
  "unicode-ident",
 ]

From abd0677d2f5e348796055e609cf640ea38964059 Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Tue, 6 Jun 2023 15:02:34 -0400
Subject: [PATCH 10/19] Merge proc_macro_span_shrink and proc_macro_span

---
 library/proc_macro/src/lib.rs                      | 4 ++--
 tests/ui/proc-macro/auxiliary/macro-only-syntax.rs | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index cb8b7ec70e0f5..7fb0d989cdbaa 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -494,13 +494,13 @@ impl Span {
     }
 
     /// Creates an empty span pointing to directly before this span.
-    #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
+    #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn start(&self) -> Span {
         Span(self.0.start())
     }
 
     /// Creates an empty span pointing to directly after this span.
-    #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
+    #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn end(&self) -> Span {
         Span(self.0.end())
     }
diff --git a/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs b/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
index faa8cfdb5ab4d..4ca3a0faa27b2 100644
--- a/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
+++ b/tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
@@ -10,7 +10,7 @@
 // lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081).
 
 #![crate_type = "proc-macro"]
-#![feature(proc_macro_span, proc_macro_span_shrink)]
+#![feature(proc_macro_span)]
 
 extern crate proc_macro;
 use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree};

From 21d9fd77f4e163dbf1124241a77e4ccbd302ac20 Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Wed, 7 Jun 2023 22:36:35 -0700
Subject: [PATCH 11/19] Delete use of proc_macro_span_shrink from proc-macro2

---
 Cargo.lock                                  | 4 ++--
 src/bootstrap/Cargo.lock                    | 4 ++--
 src/tools/miri/Cargo.lock                   | 4 ++--
 src/tools/miri/cargo-miri/Cargo.lock        | 4 ++--
 src/tools/miri/test-cargo-miri/Cargo.lock   | 4 ++--
 src/tools/miri/test_dependencies/Cargo.lock | 4 ++--
 src/tools/rust-analyzer/Cargo.lock          | 4 ++--
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9ea75799da137..f645d389ecea2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2649,9 +2649,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.57"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index d48866d58ce1b..2b2e9e9f98893 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -527,9 +527,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 7bedb5d48f64e..496c90d11fc21 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -529,9 +529,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock
index 727e46a028db0..5b8a15de1f77f 100644
--- a/src/tools/miri/cargo-miri/Cargo.lock
+++ b/src/tools/miri/cargo-miri/Cargo.lock
@@ -179,9 +179,9 @@ checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
diff --git a/src/tools/miri/test-cargo-miri/Cargo.lock b/src/tools/miri/test-cargo-miri/Cargo.lock
index af38ceb1d4c7d..cf5ec2aa883d7 100644
--- a/src/tools/miri/test-cargo-miri/Cargo.lock
+++ b/src/tools/miri/test-cargo-miri/Cargo.lock
@@ -83,9 +83,9 @@ version = "0.1.0"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.49"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
diff --git a/src/tools/miri/test_dependencies/Cargo.lock b/src/tools/miri/test_dependencies/Cargo.lock
index 8be1ee54672d8..3ed564b4cbbb7 100644
--- a/src/tools/miri/test_dependencies/Cargo.lock
+++ b/src/tools/miri/test_dependencies/Cargo.lock
@@ -193,9 +193,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.49"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 50c81ca279eee..13cb25f7b03b6 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1304,9 +1304,9 @@ version = "0.0.0"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]

From 61590752a295d0cd2b69f6cb4d0d68fbfe739eb8 Mon Sep 17 00:00:00 2001
From: Mara Bos <m-ou.se@m-ou.se>
Date: Wed, 21 Jun 2023 14:02:59 +0200
Subject: [PATCH 12/19] Remove outdated import in r-a proc macro server.

---
 src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
index e67f1e798e85a..1980d4c78bbee 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
@@ -8,10 +8,7 @@
 //!
 //! FIXME: No span and source file information is implemented yet
 
-use proc_macro::{
-    bridge::{self, server},
-    LineColumn,
-};
+use proc_macro::bridge::{self, server};
 
 mod token_stream;
 pub use token_stream::TokenStream;

From b8e4c54ffb38885a9abd11ce2903af85cb62861f Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Tue, 27 Jun 2023 14:33:04 +0200
Subject: [PATCH 13/19] Fix invalid HTML DIV tag used in HEAD

---
 src/librustdoc/html/templates/page.html | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 759c4fd601226..24f045f5ce3bf 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -24,7 +24,7 @@
       {% endfor %}
     ></script> {# #}
     {% endif %}
-    <div id="rustdoc-vars" {#+ #}
+    <meta id="rustdoc-vars" {#+ #}
          data-root-path="{{page.root_path|safe}}" {#+ #}
          data-static-root-path="{{static_root_path|safe}}" {#+ #}
          data-current-crate="{{layout.krate}}" {#+ #}
@@ -39,7 +39,6 @@
          data-theme-dark-css="{{files.theme_dark_css}}" {#+ #}
          data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #}
     > {# #}
-    </div> {# #}
     <script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #}
     {% if page.css_class.contains("crate") %}
     <script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #}

From acbfb8c3bdbcb29b23b11221ae2ec1386b061aa7 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Tue, 27 Jun 2023 17:18:50 +0200
Subject: [PATCH 14/19] Replace `id` attribute with `name` for `<meta>` tag

---
 src/librustdoc/html/markdown.rs                | 1 -
 src/librustdoc/html/static/js/source-script.js | 4 ++--
 src/librustdoc/html/static/js/storage.js       | 2 +-
 src/librustdoc/html/templates/page.html        | 2 +-
 tests/run-make/rustdoc-themes/foo.rs           | 2 +-
 5 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 1c27320024a9f..fd00277e2137d 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1525,7 +1525,6 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     map.insert("toggle-all-docs".into(), 1);
     map.insert("all-types".into(), 1);
     map.insert("default-settings".into(), 1);
-    map.insert("rustdoc-vars".into(), 1);
     map.insert("sidebar-vars".into(), 1);
     map.insert("copy-path".into(), 1);
     map.insert("TOC".into(), 1);
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index d999f3b36fd82..6eb991360404a 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -3,13 +3,13 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */
-/* global updateLocalStorage */
+/* global updateLocalStorage, getVar */
 
 "use strict";
 
 (function() {
 
-const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
+const rootPath = getVar("root-path");
 
 const NAME_OFFSET = 0;
 const DIRS_OFFSET = 1;
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 93979a944183b..71961f6f2a9c3 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -108,7 +108,7 @@ function getCurrentValue(name) {
 // Get a value from the rustdoc-vars div, which is used to convey data from
 // Rust to the JS. If there is no such element, return null.
 const getVar = (function getVar(name) {
-    const el = document.getElementById("rustdoc-vars");
+    const el = document.querySelector("head > meta[name='rustdoc-vars']");
     return el ? el.attributes["data-" + name].value : null;
 });
 
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 24f045f5ce3bf..d4ec9c34b6ffa 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -24,7 +24,7 @@
       {% endfor %}
     ></script> {# #}
     {% endif %}
-    <meta id="rustdoc-vars" {#+ #}
+    <meta name="rustdoc-vars" {#+ #}
          data-root-path="{{page.root_path|safe}}" {#+ #}
          data-static-root-path="{{static_root_path|safe}}" {#+ #}
          data-current-crate="{{layout.krate}}" {#+ #}
diff --git a/tests/run-make/rustdoc-themes/foo.rs b/tests/run-make/rustdoc-themes/foo.rs
index 995544aeff998..8b1e75b0ae13b 100644
--- a/tests/run-make/rustdoc-themes/foo.rs
+++ b/tests/run-make/rustdoc-themes/foo.rs
@@ -1,4 +1,4 @@
 // @has test.css
 // @has foo/struct.Foo.html
-// @has - '//*[@id="rustdoc-vars"]/@data-themes' 'test'
+// @has - '//*[@name="rustdoc-vars"]/@data-themes' 'test'
 pub struct Foo;

From acbab96a8e7f5f6397c9474c0f2617d7e98ec223 Mon Sep 17 00:00:00 2001
From: Boxy <supbscripter@gmail.com>
Date: Tue, 27 Jun 2023 23:52:10 +0100
Subject: [PATCH 15/19] add boxy to t-types review

---
 triagebot.toml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/triagebot.toml b/triagebot.toml
index 9248e8fc28a13..4bab8facc85b0 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -581,6 +581,7 @@ types = [
     "@lcnr",
     "@oli-obk",
     "@spastorino",
+    "@BoxyUwU",
 ]
 borrowck = [
     "@davidtwco",

From fbd1e0252fc68368379f5a85ca43d8bfd8939ca9 Mon Sep 17 00:00:00 2001
From: Eric Mark Martin <ericmarkmartin@gmail.com>
Date: Thu, 22 Jun 2023 01:52:31 -0400
Subject: [PATCH 16/19] add note for non-exhaustive matches with guards

---
 .../src/thir/pattern/check_match.rs           |  5 +++++
 .../empty-match.exhaustive_patterns.stderr    | 22 +++++++++++++------
 .../usefulness/empty-match.normal.stderr      | 22 +++++++++++++------
 tests/ui/pattern/usefulness/empty-match.rs    |  8 +++++++
 tests/ui/pattern/usefulness/issue-3601.rs     | 18 +++++++++------
 tests/ui/pattern/usefulness/issue-3601.stderr |  7 +++---
 .../usefulness/match-non-exhaustive.rs        |  1 +
 .../usefulness/match-non-exhaustive.stderr    |  1 +
 8 files changed, 60 insertions(+), 24 deletions(-)

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 e7e88351bbd1e..ff0dcdd2d1bcd 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -830,6 +830,11 @@ fn non_exhaustive_match<'p, 'tcx>(
             _ => " or multiple match arms",
         },
     );
+
+    let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some());
+    if !is_empty_match && all_arms_have_guards {
+        err.note("match arms with guards don't count towards exhaustivity");
+    }
     if let Some((span, sugg)) = suggestion {
         err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders);
     } else {
diff --git a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
index 49b6dfca62e5d..5b81a8c3d3c02 100644
--- a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
@@ -176,6 +176,7 @@ LL |     match_guarded_arm!(0u8);
    |                        ^^^ pattern `_` not covered
    |
    = note: the matched value is of type `u8`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -183,7 +184,7 @@ LL +             _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
-  --> $DIR/empty-match.rs:133:24
+  --> $DIR/empty-match.rs:134:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@@ -194,6 +195,7 @@ note: `NonEmptyStruct1` defined here
 LL | struct NonEmptyStruct1;
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -201,7 +203,7 @@ LL +             NonEmptyStruct1 => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
-  --> $DIR/empty-match.rs:137:24
+  --> $DIR/empty-match.rs:139:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@@ -212,6 +214,7 @@ note: `NonEmptyStruct2` defined here
 LL | struct NonEmptyStruct2(bool);
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -219,7 +222,7 @@ LL +             NonEmptyStruct2(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
-  --> $DIR/empty-match.rs:141:24
+  --> $DIR/empty-match.rs:144:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@@ -230,6 +233,7 @@ note: `NonEmptyUnion1` defined here
 LL | union NonEmptyUnion1 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -237,7 +241,7 @@ LL +             NonEmptyUnion1 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
-  --> $DIR/empty-match.rs:145:24
+  --> $DIR/empty-match.rs:149:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@@ -248,6 +252,7 @@ note: `NonEmptyUnion2` defined here
 LL | union NonEmptyUnion2 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -255,7 +260,7 @@ LL +             NonEmptyUnion2 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:149:24
+  --> $DIR/empty-match.rs:154:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -268,6 +273,7 @@ LL | enum NonEmptyEnum1 {
 LL |     Foo(bool),
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -275,7 +281,7 @@ LL +             NonEmptyEnum1::Foo(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:153:24
+  --> $DIR/empty-match.rs:159:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -291,6 +297,7 @@ LL |     Foo(bool),
 LL |     Bar,
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~             _ if false => {},
@@ -298,7 +305,7 @@ LL +             NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:157:24
+  --> $DIR/empty-match.rs:164:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum5::V1);
    |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -309,6 +316,7 @@ note: `NonEmptyEnum5` defined here
 LL | enum NonEmptyEnum5 {
    |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
    |
 LL ~             _ if false => {},
diff --git a/tests/ui/pattern/usefulness/empty-match.normal.stderr b/tests/ui/pattern/usefulness/empty-match.normal.stderr
index f54a3f3364ff9..6d17455086beb 100644
--- a/tests/ui/pattern/usefulness/empty-match.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match.normal.stderr
@@ -175,6 +175,7 @@ LL |     match_guarded_arm!(0u8);
    |                        ^^^ pattern `_` not covered
    |
    = note: the matched value is of type `u8`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -182,7 +183,7 @@ LL +             _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
-  --> $DIR/empty-match.rs:133:24
+  --> $DIR/empty-match.rs:134:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@@ -193,6 +194,7 @@ note: `NonEmptyStruct1` defined here
 LL | struct NonEmptyStruct1;
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -200,7 +202,7 @@ LL +             NonEmptyStruct1 => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
-  --> $DIR/empty-match.rs:137:24
+  --> $DIR/empty-match.rs:139:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@@ -211,6 +213,7 @@ note: `NonEmptyStruct2` defined here
 LL | struct NonEmptyStruct2(bool);
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -218,7 +221,7 @@ LL +             NonEmptyStruct2(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
-  --> $DIR/empty-match.rs:141:24
+  --> $DIR/empty-match.rs:144:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@@ -229,6 +232,7 @@ note: `NonEmptyUnion1` defined here
 LL | union NonEmptyUnion1 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -236,7 +240,7 @@ LL +             NonEmptyUnion1 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
-  --> $DIR/empty-match.rs:145:24
+  --> $DIR/empty-match.rs:149:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@@ -247,6 +251,7 @@ note: `NonEmptyUnion2` defined here
 LL | union NonEmptyUnion2 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -254,7 +259,7 @@ LL +             NonEmptyUnion2 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:149:24
+  --> $DIR/empty-match.rs:154:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -267,6 +272,7 @@ LL | enum NonEmptyEnum1 {
 LL |     Foo(bool),
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -274,7 +280,7 @@ LL +             NonEmptyEnum1::Foo(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:153:24
+  --> $DIR/empty-match.rs:159:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -290,6 +296,7 @@ LL |     Foo(bool),
 LL |     Bar,
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~             _ if false => {},
@@ -297,7 +304,7 @@ LL +             NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:157:24
+  --> $DIR/empty-match.rs:164:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum5::V1);
    |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -308,6 +315,7 @@ note: `NonEmptyEnum5` defined here
 LL | enum NonEmptyEnum5 {
    |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
    |
 LL ~             _ if false => {},
diff --git a/tests/ui/pattern/usefulness/empty-match.rs b/tests/ui/pattern/usefulness/empty-match.rs
index 062241faa4cf2..d56d2e3c817ce 100644
--- a/tests/ui/pattern/usefulness/empty-match.rs
+++ b/tests/ui/pattern/usefulness/empty-match.rs
@@ -128,34 +128,42 @@ fn main() {
 
     match_guarded_arm!(0u8); //~ ERROR `_` not covered
                              //~| NOTE the matched value is of type
+                             //~| NOTE match arms with guards don't count towards exhaustivity
                              //~| NOTE pattern `_` not covered
                              //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered
                                          //~| NOTE pattern `NonEmptyStruct1` not covered
                                          //~| NOTE the matched value is of type
+                                         //~| NOTE match arms with guards don't count towards exhaustivity
                                          //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered
                                                //~| NOTE the matched value is of type
                                                //~| NOTE pattern `NonEmptyStruct2(_)` not covered
+                                               //~| NOTE match arms with guards don't count towards exhaustivity
                                                //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered
                                                       //~| NOTE the matched value is of type
                                                       //~| NOTE pattern `NonEmptyUnion1 { .. }` not covered
+                                                      //~| NOTE match arms with guards don't count towards exhaustivity
                                                       //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!((NonEmptyUnion2 { foo: () })); //~ ERROR `NonEmptyUnion2 { .. }` not covered
                                                       //~| NOTE the matched value is of type
                                                       //~| NOTE pattern `NonEmptyUnion2 { .. }` not covered
+                                                      //~| NOTE match arms with guards don't count towards exhaustivity
                                                       //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
                                                   //~| NOTE the matched value is of type
                                                   //~| NOTE pattern `NonEmptyEnum1::Foo(_)` not covered
+                                                  //~| NOTE match arms with guards don't count towards exhaustivity
                                                   //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
                                                   //~| NOTE the matched value is of type
                                                   //~| NOTE patterns `NonEmptyEnum2::Foo(_)` and
+                                                  //~| NOTE match arms with guards don't count towards exhaustivity
                                                   //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
                                            //~| NOTE the matched value is of type
                                            //~| NOTE patterns `NonEmptyEnum5::V1`,
+                                           //~| NOTE match arms with guards don't count towards exhaustivity
                                            //~| NOTE in this expansion of match_guarded_arm!
 }
diff --git a/tests/ui/pattern/usefulness/issue-3601.rs b/tests/ui/pattern/usefulness/issue-3601.rs
index 6215a23980d6d..d096e39e2cf1a 100644
--- a/tests/ui/pattern/usefulness/issue-3601.rs
+++ b/tests/ui/pattern/usefulness/issue-3601.rs
@@ -1,19 +1,19 @@
 #![feature(box_patterns)]
 
 struct HTMLImageData {
-    image: Option<String>
+    image: Option<String>,
 }
 
 struct ElementData {
-    kind: Box<ElementKind>
+    kind: Box<ElementKind>,
 }
 
 enum ElementKind {
-    HTMLImageElement(HTMLImageData)
+    HTMLImageElement(HTMLImageData),
 }
 
 enum NodeKind {
-    Element(ElementData)
+    Element(ElementData),
 }
 
 struct NodeData {
@@ -25,10 +25,14 @@ fn main() {
     let ed = ElementData { kind: Box::new(ElementKind::HTMLImageElement(id)) };
     let n = NodeData { kind: Box::new(NodeKind::Element(ed)) };
 
-    // n.b. span could be better
     match n.kind {
-        box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
-            box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
+        box NodeKind::Element(ed) => match ed.kind {
+            //~^ ERROR non-exhaustive patterns
+            //~| NOTE the matched value is of type
+            //~| NOTE match arms with guards don't count towards exhaustivity
+            //~| NOTE pattern `box _` not covered
+            //~| NOTE `Box<ElementKind>` defined here
+            box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => true,
         },
     };
 }
diff --git a/tests/ui/pattern/usefulness/issue-3601.stderr b/tests/ui/pattern/usefulness/issue-3601.stderr
index 2f6b167d4f8bd..6a7c6b13e25c7 100644
--- a/tests/ui/pattern/usefulness/issue-3601.stderr
+++ b/tests/ui/pattern/usefulness/issue-3601.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `box _` not covered
-  --> $DIR/issue-3601.rs:30:44
+  --> $DIR/issue-3601.rs:29:44
    |
 LL |         box NodeKind::Element(ed) => match ed.kind {
    |                                            ^^^^^^^ pattern `box _` not covered
@@ -7,10 +7,11 @@ LL |         box NodeKind::Element(ed) => match ed.kind {
 note: `Box<ElementKind>` defined here
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
    = note: the matched value is of type `Box<ElementKind>`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~             box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true },
-LL +             box _ => todo!()
+LL ~             box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => true,
+LL ~             box _ => todo!(),
    |
 
 error: aborting due to previous error
diff --git a/tests/ui/pattern/usefulness/match-non-exhaustive.rs b/tests/ui/pattern/usefulness/match-non-exhaustive.rs
index 3b210a115d21a..62c185d04b35d 100644
--- a/tests/ui/pattern/usefulness/match-non-exhaustive.rs
+++ b/tests/ui/pattern/usefulness/match-non-exhaustive.rs
@@ -1,4 +1,5 @@
 fn main() {
     match 0 { 1 => () } //~ ERROR non-exhaustive patterns
     match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns
+    //-| NOTE match arms with guards don't count towards exhaustivity
 }
diff --git a/tests/ui/pattern/usefulness/match-non-exhaustive.stderr b/tests/ui/pattern/usefulness/match-non-exhaustive.stderr
index 08dde523a15fb..4fa3a729212b2 100644
--- a/tests/ui/pattern/usefulness/match-non-exhaustive.stderr
+++ b/tests/ui/pattern/usefulness/match-non-exhaustive.stderr
@@ -17,6 +17,7 @@ LL |     match 0 { 0 if false => () }
    |           ^ pattern `_` not covered
    |
    = note: the matched value is of type `i32`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |     match 0 { 0 if false => (), _ => todo!() }

From e79b17941212fe10f7b1bfda09d991bf5254fac4 Mon Sep 17 00:00:00 2001
From: Eric Mark Martin <ericmarkmartin@gmail.com>
Date: Wed, 28 Jun 2023 01:49:12 -0400
Subject: [PATCH 17/19] add comment back

---
 tests/ui/pattern/usefulness/issue-3601.rs     | 1 +
 tests/ui/pattern/usefulness/issue-3601.stderr | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/ui/pattern/usefulness/issue-3601.rs b/tests/ui/pattern/usefulness/issue-3601.rs
index d096e39e2cf1a..a6d2b11f4eee2 100644
--- a/tests/ui/pattern/usefulness/issue-3601.rs
+++ b/tests/ui/pattern/usefulness/issue-3601.rs
@@ -25,6 +25,7 @@ fn main() {
     let ed = ElementData { kind: Box::new(ElementKind::HTMLImageElement(id)) };
     let n = NodeData { kind: Box::new(NodeKind::Element(ed)) };
 
+    // n.b. span could be better
     match n.kind {
         box NodeKind::Element(ed) => match ed.kind {
             //~^ ERROR non-exhaustive patterns
diff --git a/tests/ui/pattern/usefulness/issue-3601.stderr b/tests/ui/pattern/usefulness/issue-3601.stderr
index 6a7c6b13e25c7..b8c9874310125 100644
--- a/tests/ui/pattern/usefulness/issue-3601.stderr
+++ b/tests/ui/pattern/usefulness/issue-3601.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `box _` not covered
-  --> $DIR/issue-3601.rs:29:44
+  --> $DIR/issue-3601.rs:30:44
    |
 LL |         box NodeKind::Element(ed) => match ed.kind {
    |                                            ^^^^^^^ pattern `box _` not covered

From 2017a176eb9e296261d7efbd0a58e8958d89841f Mon Sep 17 00:00:00 2001
From: Eric Mark Martin <ericmarkmartin@gmail.com>
Date: Wed, 28 Jun 2023 01:49:21 -0400
Subject: [PATCH 18/19] use translatable subdiagnostic

---
 compiler/rustc_mir_build/messages.ftl                    | 3 +++
 compiler/rustc_mir_build/src/errors.rs                   | 4 ++++
 compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 3 ++-
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index cb265cf2c6acb..98156840dd8a6 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -214,6 +214,9 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
 
 mir_build_non_const_path = runtime values cannot be referenced in patterns
 
+mir_build_non_exhaustive_match_all_arms_guarded =
+    match arms with guards don't count towards exhaustivity
+
 mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly
     .help = ensure that all variants are matched explicitly by adding the suggested match arms
     .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 7c0df201bc25e..df00cc75cc7a5 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -432,6 +432,10 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
     }
 }
 
+#[derive(Subdiagnostic)]
+#[note(mir_build_non_exhaustive_match_all_arms_guarded)]
+pub struct NonExhaustiveMatchAllArmsGuarded;
+
 #[derive(Diagnostic)]
 #[diag(mir_build_static_in_pattern, code = "E0158")]
 pub struct StaticInPattern {
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 ff0dcdd2d1bcd..73d8f456dc30d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -833,7 +833,8 @@ fn non_exhaustive_match<'p, 'tcx>(
 
     let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some());
     if !is_empty_match && all_arms_have_guards {
-        err.note("match arms with guards don't count towards exhaustivity");
+        err.subdiagnostic(NonExhaustiveMatchAllArmsGuarded);
+        // err.note(NonExhaustiveMatchAllArmsGuarded);
     }
     if let Some((span, sugg)) = suggestion {
         err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders);

From 96bd0566959a9b3421dbedc8450271d56b0985b5 Mon Sep 17 00:00:00 2001
From: Eric Mark Martin <ericmarkmartin@gmail.com>
Date: Wed, 28 Jun 2023 01:55:32 -0400
Subject: [PATCH 19/19] remove cruft

---
 compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 1 -
 1 file changed, 1 deletion(-)

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 73d8f456dc30d..ef60f08bf020b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -834,7 +834,6 @@ fn non_exhaustive_match<'p, 'tcx>(
     let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some());
     if !is_empty_match && all_arms_have_guards {
         err.subdiagnostic(NonExhaustiveMatchAllArmsGuarded);
-        // err.note(NonExhaustiveMatchAllArmsGuarded);
     }
     if let Some((span, sugg)) = suggestion {
         err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders);