diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index a4ab2561b721b..40e7d6430fde5 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -120,8 +120,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             self.lower_range_end(end, e2.is_some()),
                         );
                     }
-                    // FIXME(guard_patterns): lower pattern guards to HIR
-                    PatKind::Guard(inner, _) => pattern = inner,
+                    PatKind::Guard(inner, cond) => {
+                        break hir::PatKind::Guard(self.lower_pat(inner), self.lower_expr(cond));
+                    }
                     PatKind::Slice(pats) => break self.lower_pat_slice(pats),
                     PatKind::Rest => {
                         // If we reach here the `..` pattern is not semantically allowed.
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 2150759d329ea..1e29b7418540c 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -978,7 +978,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
     ) -> bool {
         let tcx = infcx.tcx;
-        let TypeTest { generic_kind, lower_bound, span: blame_span, ref verify_bound } = *type_test;
+        let TypeTest { generic_kind, lower_bound, span: blame_span, verify_bound: _ } = *type_test;
 
         let generic_ty = generic_kind.to_ty(tcx);
         let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
@@ -1016,25 +1016,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // For each region outlived by lower_bound find a non-local,
         // universal region (it may be the same region) and add it to
         // `ClosureOutlivesRequirement`.
+        let mut found_outlived_universal_region = false;
         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
+            found_outlived_universal_region = true;
             debug!("universal_region_outlived_by ur={:?}", ur);
-            // Check whether we can already prove that the "subject" outlives `ur`.
-            // If so, we don't have to propagate this requirement to our caller.
-            //
-            // To continue the example from the function, if we are trying to promote
-            // a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
-            // `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
-            // we check whether `T: '1` is something we *can* prove. If so, no need
-            // to propagate that requirement.
-            //
-            // This is needed because -- particularly in the case
-            // where `ur` is a local bound -- we are sometimes in a
-            // position to prove things that our caller cannot. See
-            // #53570 for an example.
-            if self.eval_verify_bound(infcx, generic_ty, ur, &verify_bound) {
-                continue;
-            }
-
             let non_local_ub = self.universal_region_relations.non_local_upper_bounds(ur);
             debug!(?non_local_ub);
 
@@ -1056,6 +1041,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 propagated_outlives_requirements.push(requirement);
             }
         }
+        // If we succeed to promote the subject, i.e. it only contains non-local regions,
+        // and fail to prove the type test inside of the closure, the `lower_bound` has to
+        // also be at least as large as some universal region, as the type test is otherwise
+        // trivial.
+        assert!(found_outlived_universal_region);
         true
     }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 6b4b716d9a802..2e4b6748731aa 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1387,7 +1387,7 @@ impl<'hir> Pat<'hir> {
         use PatKind::*;
         match self.kind {
             Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
-            Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
+            Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
             Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
             TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
             Slice(before, slice, after) => {
@@ -1414,7 +1414,7 @@ impl<'hir> Pat<'hir> {
         use PatKind::*;
         match self.kind {
             Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
-            Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
+            Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
             Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
             TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
             Slice(before, slice, after) => {
@@ -1566,6 +1566,9 @@ pub enum PatKind<'hir> {
     /// A literal.
     Lit(&'hir Expr<'hir>),
 
+    /// A guard pattern (e.g., `x if guard(x)`).
+    Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
+
     /// A range pattern (e.g., `1..=2` or `1..2`).
     Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd),
 
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 85e555d903b9a..f0480afd139f4 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -696,6 +696,10 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
             visit_opt!(visitor, visit_pat, slice_pattern);
             walk_list!(visitor, visit_pat, postpatterns);
         }
+        PatKind::Guard(subpat, condition) => {
+            try_visit!(visitor.visit_pat(subpat));
+            try_visit!(visitor.visit_expr(condition));
+        }
     }
     V::Result::output()
 }
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index ca6729a5bbdf6..ffc0657eebf1d 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -654,6 +654,7 @@ fn resolve_local<'tcx>(
     ///        | ( ..., P&, ... )
     ///        | ... "|" P& "|" ...
     ///        | box P&
+    ///        | P& if ...
     /// ```
     fn is_binding_pat(pat: &hir::Pat<'_>) -> bool {
         // Note that the code below looks for *explicit* refs only, that is, it won't
@@ -694,7 +695,9 @@ fn resolve_local<'tcx>(
             | PatKind::TupleStruct(_, subpats, _)
             | PatKind::Tuple(subpats, _) => subpats.iter().any(|p| is_binding_pat(p)),
 
-            PatKind::Box(subpat) | PatKind::Deref(subpat) => is_binding_pat(subpat),
+            PatKind::Box(subpat) | PatKind::Deref(subpat) | PatKind::Guard(subpat, _) => {
+                is_binding_pat(subpat)
+            }
 
             PatKind::Ref(_, _)
             | PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 42c98ab434ef7..16bb0dd328cdc 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1999,6 +1999,12 @@ impl<'a> State<'a> {
                 self.commasep(Inconsistent, after, |s, p| s.print_pat(p));
                 self.word("]");
             }
+            PatKind::Guard(inner, cond) => {
+                self.print_pat(inner);
+                self.space();
+                self.word_space("if");
+                self.print_expr(cond);
+            }
             PatKind::Err(_) => {
                 self.popen();
                 self.word("/*ERROR*/");
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index fb73985e3060b..8c8a8d6d9228a 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -456,6 +456,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Does not constitute a read.
             hir::PatKind::Wild => false,
 
+            // Might not constitute a read, since the condition might be false.
+            hir::PatKind::Guard(_, _) => true,
+
             // This is unnecessarily restrictive when the pattern that doesn't
             // constitute a read is unreachable.
             //
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index ecbae6ac72fa2..ad764e5563b94 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -615,6 +615,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                     | PatKind::Box(_)
                     | PatKind::Deref(_)
                     | PatKind::Ref(..)
+                    | PatKind::Guard(..)
                     | PatKind::Wild
                     | PatKind::Err(_) => {
                         // If the PatKind is Or, Box, or Ref, the decision is made later
@@ -1737,7 +1738,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 }
             }
 
-            PatKind::Binding(.., Some(subpat)) => {
+            PatKind::Binding(.., Some(subpat)) | PatKind::Guard(subpat, _) => {
                 self.cat_pattern(place_with_id, subpat, op)?;
             }
 
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 5a0a855147deb..a406ec9a8fbb4 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -147,8 +147,23 @@ fn typeck_with_fallback<'tcx>(
         check_abi(tcx, span, fn_sig.abi());
 
         // Compute the function signature from point of view of inside the fn.
-        let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
-        let fn_sig = fcx.normalize(body.value.span, fn_sig);
+        let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
+
+        // Normalize the input and output types one at a time, using a different
+        // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
+        // on the entire `FnSig`, since this would use the same `WellFormedLoc`
+        // for each type, preventing the HIR wf check from generating
+        // a nice error message.
+        let arg_span =
+            |idx| decl.inputs.get(idx).map_or(decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
+
+        fn_sig.inputs_and_output = tcx.mk_type_list_from_iter(
+            fn_sig
+                .inputs_and_output
+                .iter()
+                .enumerate()
+                .map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)),
+        );
 
         check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());
     } else {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 98b28240f4cb9..4870e6193c3f1 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -284,6 +284,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             PatKind::Struct(ref qpath, fields, has_rest_pat) => {
                 self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
             }
+            PatKind::Guard(pat, cond) => {
+                self.check_pat(pat, expected, pat_info);
+                self.check_expr_has_type_or_error(cond, self.tcx.types.bool, |_| {});
+                expected
+            }
             PatKind::Or(pats) => {
                 for pat in pats {
                     self.check_pat(pat, expected, pat_info);
@@ -422,7 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // An OR-pattern just propagates to each individual alternative.
             // This is maximally flexible, allowing e.g., `Some(mut x) | &Some(mut x)`.
             // In that example, `Some(mut x)` results in `Peel` whereas `&Some(mut x)` in `Reset`.
-            | PatKind::Or(_) => AdjustMode::Pass,
+            | PatKind::Or(_)
+            // Like or-patterns, guard patterns just propogate to their subpatterns.
+            | PatKind::Guard(..) => AdjustMode::Pass,
         }
     }
 
@@ -901,6 +908,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         PatKind::Struct(..)
                         | PatKind::TupleStruct(..)
                         | PatKind::Or(..)
+                        | PatKind::Guard(..)
                         | PatKind::Tuple(..)
                         | PatKind::Slice(..) => "binding",
 
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index b0150bc11920b..72f353f06ff52 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -45,10 +45,25 @@ pub trait Printer<'tcx>: Sized {
         &mut self,
         impl_def_id: DefId,
         args: &'tcx [GenericArg<'tcx>],
-        self_ty: Ty<'tcx>,
-        trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
-        self.default_print_impl_path(impl_def_id, args, self_ty, trait_ref)
+        let tcx = self.tcx();
+        let self_ty = tcx.type_of(impl_def_id);
+        let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
+        let (self_ty, impl_trait_ref) = if tcx.generics_of(impl_def_id).count() <= args.len() {
+            (
+                self_ty.instantiate(tcx, args),
+                impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(tcx, args)),
+            )
+        } else {
+            // We are probably printing a nested item inside of an impl.
+            // Use the identity substitutions for the impl.
+            (
+                self_ty.instantiate_identity(),
+                impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
+            )
+        };
+
+        self.default_print_impl_path(impl_def_id, self_ty, impl_trait_ref)
     }
 
     fn print_region(&mut self, region: ty::Region<'tcx>) -> Result<(), PrintError>;
@@ -107,23 +122,7 @@ pub trait Printer<'tcx>: Sized {
                 self.path_crate(def_id.krate)
             }
 
-            DefPathData::Impl => {
-                let generics = self.tcx().generics_of(def_id);
-                let self_ty = self.tcx().type_of(def_id);
-                let impl_trait_ref = self.tcx().impl_trait_ref(def_id);
-                let (self_ty, impl_trait_ref) = if args.len() >= generics.count() {
-                    (
-                        self_ty.instantiate(self.tcx(), args),
-                        impl_trait_ref.map(|i| i.instantiate(self.tcx(), args)),
-                    )
-                } else {
-                    (
-                        self_ty.instantiate_identity(),
-                        impl_trait_ref.map(|i| i.instantiate_identity()),
-                    )
-                };
-                self.print_impl_path(def_id, args, self_ty, impl_trait_ref)
-            }
+            DefPathData::Impl => self.print_impl_path(def_id, args),
 
             _ => {
                 let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
@@ -201,7 +200,6 @@ pub trait Printer<'tcx>: Sized {
     fn default_print_impl_path(
         &mut self,
         impl_def_id: DefId,
-        _args: &'tcx [GenericArg<'tcx>],
         self_ty: Ty<'tcx>,
         impl_trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index bdf243c87b6f1..54510faf2e182 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -435,6 +435,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
             hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },
 
+            // FIXME(guard_patterns): implement guard pattern lowering
+            hir::PatKind::Guard(pat, _) => self.lower_pattern(pat).kind,
+
             hir::PatKind::Err(guar) => PatKind::Error(guar),
         };
 
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index f9cb8c9b92716..88d69eb36788d 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -305,6 +305,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
             Deref,
             Ref,
             Lit,
+            Guard,
             Range,
             Slice,
             Err
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 0d6d8488a23ca..333ea0214eb3f 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -8,6 +8,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
 use rustc_middle::ty::{
     self, GenericArg, GenericArgKind, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt,
+    TypingEnv,
 };
 use tracing::debug;
 
@@ -383,14 +384,26 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
         &mut self,
         impl_def_id: DefId,
         args: &'tcx [GenericArg<'tcx>],
-        mut self_ty: Ty<'tcx>,
-        mut impl_trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
-        let mut typing_env = ty::TypingEnv::post_analysis(self.tcx, impl_def_id);
-        if !args.is_empty() {
-            typing_env.param_env =
-                ty::EarlyBinder::bind(typing_env.param_env).instantiate(self.tcx, args);
-        }
+        let self_ty = self.tcx.type_of(impl_def_id);
+        let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
+        let (typing_env, mut self_ty, mut impl_trait_ref) =
+            if self.tcx.generics_of(impl_def_id).count() <= args.len() {
+                (
+                    TypingEnv::fully_monomorphized(),
+                    self_ty.instantiate(self.tcx, args),
+                    impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
+                )
+            } else {
+                // We are probably printing a nested item inside of an impl.
+                // Use the identity substitutions for the impl. We also need
+                // a well-formed param-env, so let's use post-analysis.
+                (
+                    TypingEnv::post_analysis(self.tcx, impl_def_id),
+                    self_ty.instantiate_identity(),
+                    impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
+                )
+            };
 
         match &mut impl_trait_ref {
             Some(impl_trait_ref) => {
@@ -403,7 +416,7 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
             }
         }
 
-        self.default_print_impl_path(impl_def_id, args, self_ty, impl_trait_ref)
+        self.default_print_impl_path(impl_def_id, self_ty, impl_trait_ref)
     }
 }
 
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 0ca47eba5e81e..b77ad209e2bd8 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -14,8 +14,8 @@ use rustc_middle::bug;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::print::{Print, PrintError, Printer};
 use rustc_middle::ty::{
-    self, EarlyBinder, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty,
-    TyCtxt, TypeVisitable, TypeVisitableExt, UintTy,
+    self, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty, TyCtxt,
+    TypeVisitable, TypeVisitableExt, UintTy,
 };
 use rustc_span::kw;
 
@@ -227,17 +227,29 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
         &mut self,
         impl_def_id: DefId,
         args: &'tcx [GenericArg<'tcx>],
-        mut self_ty: Ty<'tcx>,
-        mut impl_trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<(), PrintError> {
         let key = self.tcx.def_key(impl_def_id);
         let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
 
-        let mut typing_env = ty::TypingEnv::post_analysis(self.tcx, impl_def_id);
-        if !args.is_empty() {
-            typing_env.param_env =
-                EarlyBinder::bind(typing_env.param_env).instantiate(self.tcx, args);
-        }
+        let self_ty = self.tcx.type_of(impl_def_id);
+        let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id);
+        let (typing_env, mut self_ty, mut impl_trait_ref) =
+            if self.tcx.generics_of(impl_def_id).count() <= args.len() {
+                (
+                    ty::TypingEnv::fully_monomorphized(),
+                    self_ty.instantiate(self.tcx, args),
+                    impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)),
+                )
+            } else {
+                // We are probably printing a nested item inside of an impl.
+                // Use the identity substitutions for the impl. We also need
+                // a well-formed param-env, so let's use post-analysis.
+                (
+                    ty::TypingEnv::post_analysis(self.tcx, impl_def_id),
+                    self_ty.instantiate_identity(),
+                    impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
+                )
+            };
 
         match &mut impl_trait_ref {
             Some(impl_trait_ref) => {
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 8aeebdde7bb45..1fb35750c15f5 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -320,6 +320,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
             );
             return Symbol::intern("()");
         }
+        PatKind::Guard(p, _) => return name_from_pat(&*p),
         PatKind::Range(..) => return kw::Underscore,
         PatKind::Slice(begin, ref mid, end) => {
             let begin = begin.iter().map(|p| name_from_pat(p).to_string());
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index e64baca974dab..7a95d33723e50 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -1,5 +1,6 @@
 use std::mem;
 
+use rustc_attr_parsing::StabilityLevel;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
 use rustc_middle::ty::{self, TyCtxt};
@@ -306,7 +307,12 @@ impl DocFolder for CacheBuilder<'_, '_> {
             | clean::ProcMacroItem(..)
             | clean::VariantItem(..) => {
                 use rustc_data_structures::fx::IndexEntry as Entry;
-                if !self.cache.stripped_mod {
+                if !self.cache.stripped_mod
+                    && !matches!(
+                        item.stability.map(|stab| stab.level),
+                        Some(StabilityLevel::Stable { allowed_through_unstable_modules: true, .. })
+                    )
+                {
                     // Re-exported items mean that the same id can show up twice
                     // in the rustdoc ast that we're looking at. We know,
                     // however, that a re-exported item doesn't show up in the
diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
index fb9f2b1526e38..9c8edfd6113f6 100644
--- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
+++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
@@ -55,7 +55,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
         | PatKind::Err(_) => false,
         PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
         PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
-        PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) => unary_pattern(x),
+        PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x),
         PatKind::Path(_) | PatKind::Lit(_) => true,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index b72a61a438499..4b731d759723c 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -254,9 +254,11 @@ impl<'a> NormalizedPat<'a> {
     fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {
         match pat.kind {
             PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,
-            PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Deref(pat) | PatKind::Ref(pat, _) => {
-                Self::from_pat(cx, arena, pat)
-            },
+            PatKind::Binding(.., Some(pat))
+            | PatKind::Box(pat)
+            | PatKind::Deref(pat)
+            | PatKind::Ref(pat, _)
+            | PatKind::Guard(pat, _) => Self::from_pat(cx, arena, pat),
             PatKind::Never => Self::Never,
             PatKind::Struct(ref path, fields, _) => {
                 let fields =
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 3ca20479f8e00..10ca6832d9c12 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -343,6 +343,10 @@ impl<'a> PatState<'a> {
                 matches!(self, Self::Wild)
             },
 
+            PatKind::Guard(..) => {
+                matches!(self, Self::Wild)
+            }
+
             // Patterns for things which can only contain a single sub-pattern.
             PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) | PatKind::Box(pat) | PatKind::Deref(pat) => {
                 self.add_pat(cx, pat)
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index d2970c93f8e91..c2dcb5ae1f9e5 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -712,6 +712,12 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 kind!("Ref({pat}, Mutability::{muta:?})");
                 self.pat(pat);
             },
+            PatKind::Guard(pat, cond) => {
+                bind!(self, pat, cond);
+                kind!("Guard({pat}, {cond})");
+                self.pat(pat);
+                self.expr(cond);
+            }
             PatKind::Lit(lit_expr) => {
                 bind!(self, lit_expr);
                 kind!("Lit({lit_expr})");
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index ed52c481de124..7c4e834f8416f 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -1104,6 +1104,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 self.hash_pat(pat);
                 std::mem::discriminant(&mu).hash(&mut self.s);
             },
+            PatKind::Guard(pat, guard) => {
+                self.hash_pat(pat);
+                self.hash_expr(guard);
+            },
             PatKind::Slice(l, m, r) => {
                 for pat in l {
                     self.hash_pat(pat);
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 30e7471dd9258..ba4a0f44584ef 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1777,7 +1777,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
                 },
             }
         },
-        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) | PatKind::Deref(_) => true,
+        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) | PatKind::Deref(_) | PatKind::Guard(..) => true,
     }
 }
 
diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs
index 4078484ff10fe..34984798ae60e 100644
--- a/src/tools/rustfmt/src/bin/main.rs
+++ b/src/tools/rustfmt/src/bin/main.rs
@@ -161,6 +161,12 @@ fn make_opts() -> Options {
         "Set options from command line. These settings take priority over .rustfmt.toml",
         "[key1=val1,key2=val2...]",
     );
+    opts.optopt(
+        "",
+        "style-edition",
+        "The edition of the Style Guide.",
+        "[2015|2018|2021|2024]",
+    );
 
     if is_nightly {
         opts.optflag(
@@ -186,12 +192,6 @@ fn make_opts() -> Options {
             "skip-children",
             "Don't reformat child modules (unstable).",
         );
-        opts.optopt(
-            "",
-            "style-edition",
-            "The edition of the Style Guide (unstable).",
-            "[2015|2018|2021|2024]",
-        );
     }
 
     opts.optflag("v", "verbose", "Print verbose output");
diff --git a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs b/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
new file mode 100644
index 0000000000000..88b0b0d57b084
--- /dev/null
+++ b/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
@@ -0,0 +1,40 @@
+//! Test case for [134702]
+//!
+//! [134702]: https://github.com/rust-lang/rust/issues/134702
+#![crate_name = "foo"]
+#![stable(since = "1.0", feature = "v1")]
+
+#![feature(staged_api, rustc_attrs)]
+
+#[stable(since = "1.0", feature = "stb1")]
+pub mod stb1 {
+    #[doc(inline)]
+    #[stable(since = "1.0", feature = "stb1")]
+    pub use crate::uns::Inside1;
+}
+
+#[unstable(feature = "uns", issue = "135003")]
+pub mod uns {
+    #[stable(since = "1.0", feature = "stb1")]
+    #[rustc_allowed_through_unstable_modules]
+    pub struct Inside1;
+    #[stable(since = "1.0", feature = "stb2")]
+    #[rustc_allowed_through_unstable_modules]
+    pub struct Inside2;
+}
+
+#[stable(since = "1.0", feature = "stb2")]
+pub mod stb2 {
+    #[doc(inline)]
+    #[stable(since = "1.0", feature = "stb2")]
+    pub use crate::uns::Inside2;
+}
+
+#[stable(since = "1.0", feature = "nested")]
+pub mod nested {
+    //! [Inside1] [Inside2]
+    //@ has foo/nested/index.html '//a[@href="../stb1/struct.Inside1.html"]' 'Inside1'
+    //@ has foo/nested/index.html '//a[@href="../stb2/struct.Inside2.html"]' 'Inside2'
+    use crate::stb1::Inside1;
+    use crate::stb2::Inside2;
+}
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
index 4cba3990049a5..db18cdf7d5aad 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -10,11 +10,12 @@ LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: S
    |                                                                                +++++++++++
 
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-for-unimpl-trait.rs:11:81
+  --> $DIR/associated-types-for-unimpl-trait.rs:11:41
    |
 LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized {}
-   |                                                                                 ^^ the trait `Get` is not implemented for `Self`
+   |                                         ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider further restricting `Self`
    |
 LL |     fn uhoh<U: Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Sized, Self: Get {}
diff --git a/tests/ui/associated-types/associated-types-no-suitable-bound.stderr b/tests/ui/associated-types/associated-types-no-suitable-bound.stderr
index 4f951ee4b4e62..b0598b3810ca4 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-bound.stderr
+++ b/tests/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -10,11 +10,12 @@ LL |     fn uhoh<T: Get>(foo: <T as Get>::Value) {}
    |              +++++
 
 error[E0277]: the trait bound `T: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-bound.rs:11:40
+  --> $DIR/associated-types-no-suitable-bound.rs:11:21
    |
 LL |     fn uhoh<T>(foo: <T as Get>::Value) {}
-   |                                        ^^ the trait `Get` is not implemented for `T`
+   |                     ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
    |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider restricting type parameter `T` with trait `Get`
    |
 LL |     fn uhoh<T: Get>(foo: <T as Get>::Value) {}
diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
index c5dcfc00925d7..fce8c7ed384d6 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
+++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
@@ -10,11 +10,12 @@ LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Ge
    |                                                              +++++++++++++++
 
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:62
+  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |                                                              ^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider further restricting `Self`
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr
index 46cebda078e46..b7d528025bd14 100644
--- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr
+++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -34,27 +34,29 @@ LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Ge
    |                                                              +++++++++++++++
 
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:17:62
+  --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |                                                              ^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider further restricting `Self`
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
    |                                                              +++++++++++++++
 
 error[E0277]: the trait bound `(T, U): Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:23:64
+  --> $DIR/associated-types-no-suitable-supertrait.rs:23:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
-   |                                                                ^^ the trait `Get` is not implemented for `(T, U)`
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/associated-types-no-suitable-supertrait.rs:12:1
    |
 LL | trait Get {
    | ^^^^^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr
index 805c3e60bb6a8..2abe337b69ae3 100644
--- a/tests/ui/associated-types/issue-59324.stderr
+++ b/tests/ui/associated-types/issue-59324.stderr
@@ -65,16 +65,17 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
    |                                     +++++
 
 error[E0277]: the trait bound `(): Foo` is not satisfied
-  --> $DIR/issue-59324.rs:23:52
+  --> $DIR/issue-59324.rs:23:29
    |
 LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
-   |                                                    ^^ the trait `Foo` is not implemented for `()`
+   |                             ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/issue-59324.rs:3:1
    |
 LL | pub trait Foo: NotFoo {
    | ^^^^^^^^^^^^^^^^^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time
   --> $DIR/issue-59324.rs:23:29
diff --git a/tests/ui/auto-traits/issue-83857-ub.stderr b/tests/ui/auto-traits/issue-83857-ub.stderr
index 7c437b7e6c84d..3536450c75b12 100644
--- a/tests/ui/auto-traits/issue-83857-ub.stderr
+++ b/tests/ui/auto-traits/issue-83857-ub.stderr
@@ -18,16 +18,10 @@ LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i
    |                                                                                +++++++++++++++++++++
 
 error[E0277]: `Foo<T, U>` cannot be sent between threads safely
-  --> $DIR/issue-83857-ub.rs:21:80
+  --> $DIR/issue-83857-ub.rs:21:35
    |
-LL |   fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
-   |  ________________________________________________________________________________^
-LL | |
-LL | |
-LL | |     f(foo(v));
-LL | |
-LL | | }
-   | |_^ `Foo<T, U>` cannot be sent between threads safely
+LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo<T, U>` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Foo<T, U>`
 note: required for `Foo<T, U>` to implement `WithAssoc`
diff --git a/tests/ui/error-codes/E0229.stderr b/tests/ui/error-codes/E0229.stderr
index ab2536cc0c9d5..7c967e89ddbc1 100644
--- a/tests/ui/error-codes/E0229.stderr
+++ b/tests/ui/error-codes/E0229.stderr
@@ -48,10 +48,10 @@ LL | fn baz<I: Foo>(x: &<I as Foo<A = Bar>>::A) {}
    |         +++++
 
 error[E0277]: the trait bound `I: Foo` is not satisfied
-  --> $DIR/E0229.rs:13:39
+  --> $DIR/E0229.rs:13:14
    |
 LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
-   |                                       ^^ the trait `Foo` is not implemented for `I`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I`
    |
 help: consider restricting type parameter `I` with trait `Foo`
    |
diff --git a/tests/ui/feature-gates/feature-gate-guard-patterns.rs b/tests/ui/feature-gates/feature-gate-guard-patterns.rs
index 929e8ef3181f9..52ed89e668b1f 100644
--- a/tests/ui/feature-gates/feature-gate-guard-patterns.rs
+++ b/tests/ui/feature-gates/feature-gate-guard-patterns.rs
@@ -1,3 +1,5 @@
+#![allow(irrefutable_let_patterns)]
+
 fn match_guards_still_work() {
     match 0 {
         0 if guard(0) => {},
@@ -24,11 +26,9 @@ fn other_guards_dont() {
 
     if let (x if guard(x)) = 0 {}
     //~^ ERROR: guard patterns are experimental
-    //~| WARN: irrefutable
 
     while let (x if guard(x)) = 0 {}
     //~^ ERROR: guard patterns are experimental
-    //~| WARN: irrefutable
 
     #[cfg(FALSE)]
     while let (x if guard(x)) = 0 {}
diff --git a/tests/ui/feature-gates/feature-gate-guard-patterns.stderr b/tests/ui/feature-gates/feature-gate-guard-patterns.stderr
index 0613b5c95a413..8b85b663889f7 100644
--- a/tests/ui/feature-gates/feature-gate-guard-patterns.stderr
+++ b/tests/ui/feature-gates/feature-gate-guard-patterns.stderr
@@ -1,5 +1,5 @@
 error: unexpected parentheses surrounding `match` arm pattern
-  --> $DIR/feature-gate-guard-patterns.rs:10:9
+  --> $DIR/feature-gate-guard-patterns.rs:12:9
    |
 LL |         (0 if guard(0)) => {},
    |         ^             ^
@@ -11,7 +11,7 @@ LL +         0 if guard(0) => {},
    |
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/feature-gate-guard-patterns.rs:21:22
+  --> $DIR/feature-gate-guard-patterns.rs:23:22
    |
 LL |     let ((x if guard(x)) | x) = 0;
    |                      ^ not found in this scope
@@ -23,13 +23,13 @@ LL | fn even_as_function_parameters(((x if guard(x), _) | (_, x)): (i32, i32)) {
    |                                             ^
    |
 help: the binding `x` is available in a different scope in the same function
-  --> $DIR/feature-gate-guard-patterns.rs:21:11
+  --> $DIR/feature-gate-guard-patterns.rs:23:11
    |
 LL |     let ((x if guard(x)) | x) = 0;
    |           ^
 
 error[E0658]: guard patterns are experimental
-  --> $DIR/feature-gate-guard-patterns.rs:16:15
+  --> $DIR/feature-gate-guard-patterns.rs:18:15
    |
 LL |         (0 if guard(0)) | 1 => {},
    |               ^^^^^^^^
@@ -40,7 +40,7 @@ LL |         (0 if guard(0)) | 1 => {},
    = help: consider using match arm guards
 
 error[E0658]: guard patterns are experimental
-  --> $DIR/feature-gate-guard-patterns.rs:21:16
+  --> $DIR/feature-gate-guard-patterns.rs:23:16
    |
 LL |     let ((x if guard(x)) | x) = 0;
    |                ^^^^^^^^
@@ -51,7 +51,7 @@ LL |     let ((x if guard(x)) | x) = 0;
    = help: consider using match arm guards
 
 error[E0658]: guard patterns are experimental
-  --> $DIR/feature-gate-guard-patterns.rs:25:18
+  --> $DIR/feature-gate-guard-patterns.rs:27:18
    |
 LL |     if let (x if guard(x)) = 0 {}
    |                  ^^^^^^^^
@@ -62,7 +62,7 @@ LL |     if let (x if guard(x)) = 0 {}
    = help: consider using match arm guards
 
 error[E0658]: guard patterns are experimental
-  --> $DIR/feature-gate-guard-patterns.rs:29:21
+  --> $DIR/feature-gate-guard-patterns.rs:30:21
    |
 LL |     while let (x if guard(x)) = 0 {}
    |                     ^^^^^^^^
@@ -94,26 +94,7 @@ LL | fn even_as_function_parameters(((x if guard(x), _) | (_, x)): (i32, i32)) {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: consider using match arm guards
 
-warning: irrefutable `if let` pattern
-  --> $DIR/feature-gate-guard-patterns.rs:25:8
-   |
-LL |     if let (x if guard(x)) = 0 {}
-   |        ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this pattern will always match, so the `if let` is useless
-   = help: consider replacing the `if let` with a `let`
-   = note: `#[warn(irrefutable_let_patterns)]` on by default
-
-warning: irrefutable `while let` pattern
-  --> $DIR/feature-gate-guard-patterns.rs:29:11
-   |
-LL |     while let (x if guard(x)) = 0 {}
-   |           ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this pattern will always match, so the loop will never exit
-   = help: consider instead using a `loop { ... }` with a `let` inside it
-
-error: aborting due to 9 previous errors; 2 warnings emitted
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0425, E0658.
 For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/issues/issue-18611.stderr b/tests/ui/issues/issue-18611.stderr
index 918654215b372..4fa699de63527 100644
--- a/tests/ui/issues/issue-18611.stderr
+++ b/tests/ui/issues/issue-18611.stderr
@@ -11,19 +11,17 @@ LL | trait HasState {
    | ^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `isize: HasState` is not satisfied
-  --> $DIR/issue-18611.rs:1:46
+  --> $DIR/issue-18611.rs:1:18
    |
-LL |   fn add_state(op: <isize as HasState>::State) {
-   |  ______________________________________________^
-...  |
-LL | | }
-   | |_^ the trait `HasState` is not implemented for `isize`
+LL | fn add_state(op: <isize as HasState>::State) {
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/issue-18611.rs:6:1
    |
 LL | trait HasState {
    | ^^^^^^^^^^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/issues/issue-35570.stderr
index 0aa6b5e402e44..b39b15fdf4b10 100644
--- a/tests/ui/issues/issue-35570.stderr
+++ b/tests/ui/issues/issue-35570.stderr
@@ -11,15 +11,10 @@ LL | trait Trait2<'a> {
    | ^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
-  --> $DIR/issue-35570.rs:8:66
+  --> $DIR/issue-35570.rs:8:16
    |
-LL |   fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
-   |  __________________________________________________________________^
-LL | |
-LL | |
-LL | |     let _e: (usize, usize) = unsafe{mem::transmute(param)};
-LL | | }
-   | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
+LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/issue-35570.rs:4:1
diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr
index 2e8668f60de74..aa6b3da6da995 100644
--- a/tests/ui/proc-macro/bad-projection.stderr
+++ b/tests/ui/proc-macro/bad-projection.stderr
@@ -48,16 +48,17 @@ LL | trait Project {
    | ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `(): Project` is not satisfied
-  --> $DIR/bad-projection.rs:14:40
+  --> $DIR/bad-projection.rs:14:17
    |
 LL | pub fn uwu() -> <() as Project>::Assoc {}
-   |                                        ^^ the trait `Project` is not implemented for `()`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^ the trait `Project` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/bad-projection.rs:9:1
    |
 LL | trait Project {
    | ^^^^^^^^^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
index 4d77a551f6472..1106352037a08 100644
--- a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
+++ b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
@@ -20,8 +20,8 @@ trait Trait2<'a, 'b> {
 // do not infer that.
 fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
     //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
+    //~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
 {
-    //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
 }
 
 fn main() { }
diff --git a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
index 87f0f47f2401e..643746ed46fcf 100644
--- a/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
+++ b/tests/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
@@ -10,12 +10,10 @@ LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T
    |                    ++++++++++++++++++++++++
 
 error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
-  --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:23:1
+  --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25
    |
-LL | / {
-LL | |
-LL | | }
-   | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
+LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
    |
 help: consider restricting type parameter `T` with trait `Trait2`
    |
diff --git a/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr
index b2118ccd81b67..2ed614f1857d4 100644
--- a/tests/ui/specialization/min_specialization/issue-79224.stderr
+++ b/tests/ui/specialization/min_specialization/issue-79224.stderr
@@ -35,13 +35,10 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
    |                +++++++++++++++++++
 
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:30:62
+  --> $DIR/issue-79224.rs:30:12
    |
-LL |       fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-   |  ______________________________________________________________^
-...  |
-LL | |     }
-   | |_____^ the trait `Clone` is not implemented for `B`
+LL |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+   |            ^^^^^ the trait `Clone` is not implemented for `B`
    |
    = note: required for `B` to implement `ToOwned`
 help: consider further restricting type parameter `B` with trait `Clone`
diff --git a/tests/ui/symbol-names/normalize-in-param-env.rs b/tests/ui/symbol-names/normalize-in-param-env.rs
new file mode 100644
index 0000000000000..a1453eb13eff5
--- /dev/null
+++ b/tests/ui/symbol-names/normalize-in-param-env.rs
@@ -0,0 +1,38 @@
+//@ revisions: legacy v0
+//@[v0] compile-flags: -C symbol-mangling-version=v0
+//@[legacy] compile-flags: -C symbol-mangling-version=legacy -Zunstable-options
+//@ build-pass
+
+pub struct Vec2;
+
+pub trait Point {
+    type S;
+}
+impl Point for Vec2 {
+    type S = f32;
+}
+
+pub trait Point2: Point<S = Self::S2> {
+    type S2;
+}
+impl Point2 for Vec2 {
+    type S2 = Self::S;
+}
+
+trait MyFrom<T> {
+    fn my_from();
+}
+impl<P: Point2> MyFrom<P::S> for P {
+    fn my_from() {
+        // This is just a really dumb way to force the legacy symbol mangling to
+        // mangle the closure's parent impl def path *with* args. Otherwise,
+        // legacy symbol mangling will strip the args from the instance, meaning
+        // that we don't trigger the bug.
+        let c = || {};
+        let x = Box::new(c) as Box<dyn Fn()>;
+    }
+}
+
+fn main() {
+    <Vec2 as MyFrom<_>>::my_from();
+}
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
index 98f99cdbfbd65..c24f8fd867fb3 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -15,21 +15,17 @@ LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
    |                    +++++++
 
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/generic_underconstrained.rs:9:51
+  --> $DIR/generic_underconstrained.rs:9:31
    |
-LL |   fn underconstrain<T>(_: T) -> Underconstrained<T> {
-   |  ___________________________________________________^
-LL | |
-LL | |
-LL | |     unimplemented!()
-LL | | }
-   | |_^ the trait `Trait` is not implemented for `T`
+LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
+   |                               ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
    |
 note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained.rs:6:26
    |
 LL | type Underconstrained<T: Trait> = impl Send;
    |                          ^^^^^ required by this bound
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider restricting type parameter `T` with trait `Trait`
    |
 LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
index 5506977a3e702..93df5ddca796f 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -31,42 +31,34 @@ LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained
    |                          +++++++++++++++++
 
 error[E0277]: `U` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:8:53
+  --> $DIR/generic_underconstrained2.rs:8:33
    |
-LL |   fn underconstrained<U>(_: U) -> Underconstrained<U> {
-   |  _____________________________________________________^
-LL | |
-LL | |
-LL | |     5u32
-LL | | }
-   | |_^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
+   |                                 ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained2.rs:5:26
    |
 LL | type Underconstrained<T: std::fmt::Debug> = impl Send;
    |                          ^^^^^^^^^^^^^^^ required by this bound
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider restricting type parameter `U` with trait `Debug`
    |
 LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
    |                      +++++++++++++++++
 
 error[E0277]: `V` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:17:64
+  --> $DIR/generic_underconstrained2.rs:17:43
    |
-LL |   fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
-   |  ________________________________________________________________^
-LL | |
-LL | |
-LL | |     5u32
-LL | | }
-   | |_^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
+   |                                           ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained2`
   --> $DIR/generic_underconstrained2.rs:14:27
    |
 LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
    |                           ^^^^^^^^^^^^^^^ required by this bound
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: consider restricting type parameter `V` with trait `Debug`
    |
 LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {