about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs21
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/util/classify.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs50
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs16
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs48
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs34
-rw-r--r--compiler/rustc_builtin_macros/src/util.rs32
-rw-r--r--compiler/rustc_expand/src/build.rs21
-rw-r--r--compiler/rustc_hir/src/hir.rs15
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs4
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs8
-rw-r--r--compiler/rustc_index_macros/Cargo.toml2
-rw-r--r--compiler/rustc_lint/src/traits.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs2
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs3
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/path.rs4
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs14
-rw-r--r--compiler/rustc_parse_format/src/lib.rs8
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs37
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs5
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs2
-rw-r--r--library/core/src/macros/mod.rs18
-rw-r--r--library/core/src/ptr/const_ptr.rs41
-rw-r--r--library/core/src/ptr/mut_ptr.rs40
-rw-r--r--src/librustdoc/clean/mod.rs8
-rw-r--r--src/librustdoc/doctest.rs3
-rw-r--r--src/librustdoc/doctest/runner.rs42
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/types/borrowed_box.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/type_complexity.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs5
-rw-r--r--src/tools/compiletest/src/common.rs10
-rwxr-xr-xsrc/tools/publish_toolstate.py4
-rw-r--r--src/tools/rustfmt/src/spanned.rs2
-rw-r--r--src/tools/rustfmt/src/types.rs12
-rw-r--r--tests/run-make/README.md2
-rw-r--r--tests/run-make/non-unicode-env/non_unicode_env.rs1
-rw-r--r--tests/run-make/non-unicode-env/non_unicode_env.stderr10
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs2
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr4
-rw-r--r--tests/ui/abi/unsupported.aarch64.stderr20
-rw-r--r--tests/ui/abi/unsupported.arm.stderr18
-rw-r--r--tests/ui/abi/unsupported.i686.stderr14
-rw-r--r--tests/ui/abi/unsupported.riscv32.stderr18
-rw-r--r--tests/ui/abi/unsupported.riscv64.stderr18
-rw-r--r--tests/ui/abi/unsupported.x64.stderr18
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs4
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr4
-rw-r--r--tests/ui/fmt/closing-brace-as-fill.rs2
-rw-r--r--tests/ui/fmt/closing-brace-as-fill.stderr6
-rw-r--r--tests/ui/fmt/format-string-error-2.rs2
-rw-r--r--tests/ui/fmt/format-string-error-2.stderr56
-rw-r--r--tests/ui/fmt/format-string-error.rs6
-rw-r--r--tests/ui/fmt/format-string-error.stderr24
-rw-r--r--tests/ui/fmt/format-string-wrong-order.rs4
-rw-r--r--tests/ui/fmt/format-string-wrong-order.stderr8
-rw-r--r--tests/ui/fmt/ifmt-bad-arg.rs2
-rw-r--r--tests/ui/fmt/ifmt-bad-arg.stderr8
-rw-r--r--tests/ui/fmt/issue-91556.rs4
-rw-r--r--tests/ui/fmt/issue-91556.stderr4
-rw-r--r--tests/ui/fmt/respanned-literal-issue-106191.rs4
-rw-r--r--tests/ui/fmt/respanned-literal-issue-106191.stderr8
-rw-r--r--tests/ui/macros/issue-51848.stderr4
-rw-r--r--tests/ui/use/unused-trait-with-method-err.rs17
-rw-r--r--tests/ui/use/unused-trait-with-method-err.stderr19
93 files changed, 558 insertions, 420 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 3e2757ac023..02cb6f188a7 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -308,7 +308,7 @@ impl TraitBoundModifiers {
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum GenericBound {
-    Trait(PolyTraitRef, TraitBoundModifiers),
+    Trait(PolyTraitRef),
     Outlives(Lifetime),
     /// Precise capturing syntax: `impl Sized + use<'a>`
     Use(ThinVec<PreciseCapturingArg>, Span),
@@ -1213,10 +1213,12 @@ impl Expr {
 
     pub fn to_bound(&self) -> Option<GenericBound> {
         match &self.kind {
-            ExprKind::Path(None, path) => Some(GenericBound::Trait(
-                PolyTraitRef::new(ThinVec::new(), path.clone(), self.span),
+            ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
+                ThinVec::new(),
+                path.clone(),
                 TraitBoundModifiers::NONE,
-            )),
+                self.span,
+            ))),
             _ => None,
         }
     }
@@ -2972,6 +2974,9 @@ pub struct PolyTraitRef {
     /// The `'a` in `for<'a> Foo<&'a T>`.
     pub bound_generic_params: ThinVec<GenericParam>,
 
+    // Optional constness, asyncness, or polarity.
+    pub modifiers: TraitBoundModifiers,
+
     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
     pub trait_ref: TraitRef,
 
@@ -2979,9 +2984,15 @@ pub struct PolyTraitRef {
 }
 
 impl PolyTraitRef {
-    pub fn new(generic_params: ThinVec<GenericParam>, path: Path, span: Span) -> Self {
+    pub fn new(
+        generic_params: ThinVec<GenericParam>,
+        path: Path,
+        modifiers: TraitBoundModifiers,
+        span: Span,
+    ) -> Self {
         PolyTraitRef {
             bound_generic_params: generic_params,
+            modifiers,
             trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
             span,
         }
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 6bdd69e7101..2afbd979c30 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -913,7 +913,7 @@ fn walk_fn_ret_ty<T: MutVisitor>(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
 
 fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
     match pb {
-        GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty),
+        GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
         GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
         GenericBound::Use(args, span) => {
             for arg in args {
@@ -1034,7 +1034,7 @@ fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut Tr
 }
 
 fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
-    let PolyTraitRef { bound_generic_params, trait_ref, span } = p;
+    let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p;
     bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
     vis.visit_trait_ref(trait_ref);
     vis.visit_span(span);
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index fcc1af5ebc2..ae1ca36a3ba 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -265,7 +265,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
 
             ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => {
                 match bounds.last() {
-                    Some(ast::GenericBound::Trait(bound, _)) => {
+                    Some(ast::GenericBound::Trait(bound)) => {
                         match path_return_type(&bound.trait_ref.path) {
                             Some(trailing_ty) => ty = trailing_ty,
                             None => break None,
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index a8f0e41167d..207ec710650 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef)
 where
     V: Visitor<'a>,
 {
-    let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref;
+    let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref;
     walk_list!(visitor, visit_generic_param, bound_generic_params);
     visitor.visit_trait_ref(trait_ref)
 }
@@ -721,7 +721,7 @@ impl WalkItemKind for ForeignItemKind {
 
 pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
     match bound {
-        GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
+        GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref),
         GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
         GenericBound::Use(args, _span) => {
             walk_list!(visitor, visit_precise_capturing_arg, args);
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 1273b50dff8..ce744cc56e1 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
             for bound in &bound_pred.bounds {
                 if !matches!(
                     *bound,
-                    GenericBound::Trait(_, TraitBoundModifiers {
-                        polarity: BoundPolarity::Maybe(_),
+                    GenericBound::Trait(PolyTraitRef {
+                        modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
                         ..
                     })
                 ) {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5738f891281..00eafeb4d84 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1224,13 +1224,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 let bound = this.lower_poly_trait_ref(
                     &PolyTraitRef {
                         bound_generic_params: ThinVec::new(),
+                        modifiers: TraitBoundModifiers::NONE,
                         trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
                         span: t.span,
                     },
                     itctx,
-                    TraitBoundModifiers::NONE,
                 );
-                let bound = (bound, hir::TraitBoundModifier::None);
                 let bounds = this.arena.alloc_from_iter([bound]);
                 let lifetime_bound = this.elided_dyn_bound(t.span);
                 (bounds, lifetime_bound)
@@ -1357,10 +1356,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             // We can safely ignore constness here since AST validation
                             // takes care of rejecting invalid modifier combinations and
                             // const trait bounds in trait object types.
-                            GenericBound::Trait(ty, modifiers) => {
-                                let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers);
-                                let polarity = this.lower_trait_bound_modifiers(*modifiers);
-                                Some((trait_ref, polarity))
+                            GenericBound::Trait(ty) => {
+                                let trait_ref = this.lower_poly_trait_ref(ty, itctx);
+                                Some(trait_ref)
                             }
                             GenericBound::Outlives(lifetime) => {
                                 if lifetime_bound.is_none() {
@@ -1993,21 +1991,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             span_ext: DUMMY_SP,
         });
 
-        hir::GenericBound::Trait(
-            hir::PolyTraitRef {
-                bound_generic_params: &[],
-                trait_ref: hir::TraitRef {
-                    path: self.make_lang_item_path(
-                        trait_lang_item,
-                        opaque_ty_span,
-                        Some(bound_args),
-                    ),
-                    hir_ref_id: self.next_id(),
-                },
-                span: opaque_ty_span,
+        hir::GenericBound::Trait(hir::PolyTraitRef {
+            bound_generic_params: &[],
+            modifiers: hir::TraitBoundModifier::None,
+            trait_ref: hir::TraitRef {
+                path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
+                hir_ref_id: self.next_id(),
             },
-            hir::TraitBoundModifier::None,
-        )
+            span: opaque_ty_span,
+        })
     }
 
     #[instrument(level = "trace", skip(self))]
@@ -2017,10 +2009,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         itctx: ImplTraitContext,
     ) -> hir::GenericBound<'hir> {
         match tpb {
-            GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(p, itctx, *modifiers),
-                self.lower_trait_bound_modifiers(*modifiers),
-            ),
+            GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
             GenericBound::Outlives(lifetime) => {
                 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
             }
@@ -2224,12 +2213,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         p: &PolyTraitRef,
         itctx: ImplTraitContext,
-        modifiers: ast::TraitBoundModifiers,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
             self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
-        let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx);
-        hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
+        let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
+        let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
+        hir::PolyTraitRef {
+            bound_generic_params,
+            modifiers,
+            trait_ref,
+            span: self.lower_span(p.span),
+        }
     }
 
     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
@@ -2669,10 +2663,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
                         let principal = hir::PolyTraitRef {
                             bound_generic_params: &[],
+                            modifiers: hir::TraitBoundModifier::None,
                             trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
                             span: self.lower_span(span),
                         };
-                        let principal = (principal, hir::TraitBoundModifier::None);
 
                         // The original ID is taken by the `PolyTraitRef`,
                         // so the `Ty` itself needs a different one.
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a36a9f11c0f..20a4f2120dc 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1263,7 +1263,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     if !bound_pred.bound_generic_params.is_empty() {
                         for bound in &bound_pred.bounds {
                             match bound {
-                                GenericBound::Trait(t, _) => {
+                                GenericBound::Trait(t) => {
                                     if !t.bound_generic_params.is_empty() {
                                         self.dcx()
                                             .emit_err(errors::NestedLifetimes { span: t.span });
@@ -1283,8 +1283,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
     fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
         match bound {
-            GenericBound::Trait(trait_ref, modifiers) => {
-                match (ctxt, modifiers.constness, modifiers.polarity) {
+            GenericBound::Trait(trait_ref) => {
+                match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) {
                     (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
                         if !self.features.more_maybe_bounds =>
                     {
@@ -1324,7 +1324,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
 
                 // Negative trait bounds are not allowed to have associated constraints
-                if let BoundPolarity::Negative(_) = modifiers.polarity
+                if let BoundPolarity::Negative(_) = trait_ref.modifiers.polarity
                     && let Some(segment) = trait_ref.trait_ref.path.segments.last()
                 {
                     match segment.args.as_deref() {
@@ -1672,7 +1672,9 @@ fn deny_equality_constraints(
             }),
         ) {
             for bound in bounds {
-                if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
+                if let GenericBound::Trait(poly) = bound
+                    && poly.modifiers == TraitBoundModifiers::NONE
+                {
                     if full_path.segments[..full_path.segments.len() - 1]
                         .iter()
                         .map(|segment| segment.ident.name)
@@ -1700,7 +1702,9 @@ fn deny_equality_constraints(
             ) {
                 if ident == potential_param.ident {
                     for bound in bounds {
-                        if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
+                        if let ast::GenericBound::Trait(poly) = bound
+                            && poly.modifiers == TraitBoundModifiers::NONE
+                        {
                             suggest(poly, potential_assoc, predicate);
                         }
                     }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 39ff237b835..2cdec2138ad 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -8,7 +8,6 @@ mod item;
 
 use std::borrow::Cow;
 
-use ast::TraitBoundModifiers;
 use rustc_ast::attr::AttrIdGenerator;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{
@@ -1259,6 +1258,27 @@ impl<'a> State<'a> {
 
     fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
         self.print_formal_generic_params(&t.bound_generic_params);
+
+        let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers;
+        match constness {
+            ast::BoundConstness::Never => {}
+            ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => {
+                self.word_space(constness.as_str());
+            }
+        }
+        match asyncness {
+            ast::BoundAsyncness::Normal => {}
+            ast::BoundAsyncness::Async(_) => {
+                self.word_space(asyncness.as_str());
+            }
+        }
+        match polarity {
+            ast::BoundPolarity::Positive => {}
+            ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
+                self.word(polarity.as_str());
+            }
+        }
+
         self.print_trait_ref(&t.trait_ref)
     }
 
@@ -1746,31 +1766,7 @@ impl<'a> State<'a> {
             }
 
             match bound {
-                GenericBound::Trait(
-                    tref,
-                    TraitBoundModifiers { constness, asyncness, polarity },
-                ) => {
-                    match constness {
-                        ast::BoundConstness::Never => {}
-                        ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => {
-                            self.word_space(constness.as_str());
-                        }
-                    }
-
-                    match asyncness {
-                        ast::BoundAsyncness::Normal => {}
-                        ast::BoundAsyncness::Async(_) => {
-                            self.word_space(asyncness.as_str());
-                        }
-                    }
-
-                    match polarity {
-                        ast::BoundPolarity::Positive => {}
-                        ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
-                            self.word(polarity.as_str());
-                        }
-                    }
-
+                GenericBound::Trait(tref) => {
                     self.print_poly_trait_ref(tref);
                 }
                 GenericBound::Outlives(lt) => self.print_lifetime(*lt),
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 39175b406a4..6333d59a1bc 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -254,7 +254,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         debug!(?hrtb_bounds);
 
         hrtb_bounds.iter().for_each(|bound| {
-            let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else {
+            let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }) = bound else {
                 return;
             };
             diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static);
@@ -277,7 +277,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     return;
                 };
                 bounds.iter().for_each(|bd| {
-                    if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }, _) = bd
+                    if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }) = bd
                         && let Def(_, res_defid) = tr_ref.path.res
                         && res_defid == trait_res_defid // trait id matches
                         && let TyKind::Path(Resolved(_, path)) = bounded_ty.kind
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 1a5f9bdb154..b4b8373ac97 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -837,7 +837,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
                 hir_ty
             );
         };
-        if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty
+        if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref)], .. } = opaque_ty
             && let Some(segment) = trait_ref.trait_ref.path.segments.last()
             && let Some(args) = segment.args
             && let [constraint] = args.constraints
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index e3878d90e41..731945f5cbf 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee:
 }
 
 fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
-    if let GenericBound::Trait(
-        trait_ref,
-        TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. },
-    ) = bound
+    if let GenericBound::Trait(trait_ref) = bound
+        && let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } =
+            trait_ref.modifiers
+        && is_sized_marker(&trait_ref.trait_ref.path)
     {
-        is_sized_marker(&trait_ref.trait_ref.path)
+        true
     } else {
         false
     }
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 25583cda5a2..43e2bf1796f 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -15,7 +15,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use thin_vec::thin_vec;
 
 use crate::errors;
-use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts};
+use crate::util::{expr_to_string, get_exprs_from_tts, get_single_expr_from_tts};
 
 fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result<Symbol, VarError> {
     let var = var.as_str();
@@ -32,19 +32,28 @@ pub(crate) fn expand_option_env<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> MacroExpanderResult<'cx> {
-    let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "option_env!") else {
+    let ExpandResult::Ready(mac_expr) = get_single_expr_from_tts(cx, sp, tts, "option_env!") else {
+        return ExpandResult::Retry(());
+    };
+    let var_expr = match mac_expr {
+        Ok(var_expr) => var_expr,
+        Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
+    };
+    let ExpandResult::Ready(mac) =
+        expr_to_string(cx, var_expr.clone(), "argument must be a string literal")
+    else {
         return ExpandResult::Retry(());
     };
     let var = match mac {
-        Ok(var) => var,
+        Ok((var, _)) => var,
         Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
     };
 
     let sp = cx.with_def_site_ctxt(sp);
-    let value = lookup_env(cx, var).ok();
-    cx.sess.psess.env_depinfo.borrow_mut().insert((var, value));
+    let value = lookup_env(cx, var);
+    cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied()));
     let e = match value {
-        None => {
+        Err(VarError::NotPresent) => {
             let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
             cx.expr_path(cx.path_all(
                 sp,
@@ -58,7 +67,18 @@ pub(crate) fn expand_option_env<'cx>(
                 ))],
             ))
         }
-        Some(value) => {
+        Err(VarError::NotUnicode(_)) => {
+            let ExprKind::Lit(token::Lit {
+                kind: LitKind::Str | LitKind::StrRaw(..), symbol, ..
+            }) = &var_expr.kind
+            else {
+                unreachable!("`expr_to_string` ensures this is a string lit")
+            };
+
+            let guar = cx.dcx().emit_err(errors::EnvNotUnicode { span: sp, var: *symbol });
+            return ExpandResult::Ready(DummyResult::any(sp, guar));
+        }
+        Ok(value) => {
             cx.expr_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![
                 cx.expr_str(sp, value)
             ])
diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs
index d7b03a43ecb..2a28dfaf3c4 100644
--- a/compiler/rustc_builtin_macros/src/util.rs
+++ b/compiler/rustc_builtin_macros/src/util.rs
@@ -171,6 +171,30 @@ pub(crate) fn get_single_str_spanned_from_tts(
     tts: TokenStream,
     name: &str,
 ) -> ExpandResult<Result<(Symbol, Span), ErrorGuaranteed>, ()> {
+    let ExpandResult::Ready(ret) = get_single_expr_from_tts(cx, span, tts, name) else {
+        return ExpandResult::Retry(());
+    };
+    let ret = match ret {
+        Ok(ret) => ret,
+        Err(e) => return ExpandResult::Ready(Err(e)),
+    };
+    expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
+        res.map_err(|err| match err {
+            Ok((err, _)) => err.emit(),
+            Err(guar) => guar,
+        })
+        .map(|(symbol, _style, span)| (symbol, span))
+    })
+}
+
+/// Interpreting `tts` as a comma-separated sequence of expressions,
+/// expect exactly one expression, or emit an error and return `Err`.
+pub(crate) fn get_single_expr_from_tts(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    tts: TokenStream,
+    name: &str,
+) -> ExpandResult<Result<P<ast::Expr>, ErrorGuaranteed>, ()> {
     let mut p = cx.new_parser_from_tts(tts);
     if p.token == token::Eof {
         let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
@@ -185,13 +209,7 @@ pub(crate) fn get_single_str_spanned_from_tts(
     if p.token != token::Eof {
         cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
     }
-    expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
-        res.map_err(|err| match err {
-            Ok((err, _)) => err.emit(),
-            Err(guar) => guar,
-        })
-        .map(|(symbol, _style, span)| (symbol, span))
-    })
+    ExpandResult::Ready(Ok(ret))
 }
 
 /// Extracts comma-separated expressions from `tts`.
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 743a9854f79..a673e2e3250 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -143,24 +143,25 @@ impl<'a> ExtCtxt<'a> {
         ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
     }
 
-    pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
+    pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef {
         ast::PolyTraitRef {
             bound_generic_params: ThinVec::new(),
+            modifiers: ast::TraitBoundModifiers {
+                polarity: ast::BoundPolarity::Positive,
+                constness: if is_const {
+                    ast::BoundConstness::Maybe(DUMMY_SP)
+                } else {
+                    ast::BoundConstness::Never
+                },
+                asyncness: ast::BoundAsyncness::Normal,
+            },
             trait_ref: self.trait_ref(path),
             span,
         }
     }
 
     pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound {
-        ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifiers {
-            polarity: ast::BoundPolarity::Positive,
-            constness: if is_const {
-                ast::BoundConstness::Maybe(DUMMY_SP)
-            } else {
-                ast::BoundConstness::Never
-            },
-            asyncness: ast::BoundAsyncness::Normal,
-        })
+        ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const))
     }
 
     pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index bc5ed249559..009c6c4aea5 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -519,7 +519,7 @@ pub enum TraitBoundModifier {
 
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
 pub enum GenericBound<'hir> {
-    Trait(PolyTraitRef<'hir>, TraitBoundModifier),
+    Trait(PolyTraitRef<'hir>),
     Outlives(&'hir Lifetime),
     Use(&'hir [PreciseCapturingArg<'hir>], Span),
 }
@@ -527,7 +527,7 @@ pub enum GenericBound<'hir> {
 impl GenericBound<'_> {
     pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
         match self {
-            GenericBound::Trait(data, _) => Some(&data.trait_ref),
+            GenericBound::Trait(data) => Some(&data.trait_ref),
             _ => None,
         }
     }
@@ -2873,11 +2873,7 @@ pub enum TyKind<'hir> {
     OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
-    TraitObject(
-        &'hir [(PolyTraitRef<'hir>, TraitBoundModifier)],
-        &'hir Lifetime,
-        TraitObjectSyntax,
-    ),
+    TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
     /// Unused for now.
     Typeof(&'hir AnonConst),
     /// `TyKind::Infer` means the type should be inferred instead of it having been
@@ -3181,6 +3177,11 @@ pub struct PolyTraitRef<'hir> {
     /// The `'a` in `for<'a> Foo<&'a T>`.
     pub bound_generic_params: &'hir [GenericParam<'hir>],
 
+    /// The constness and polarity of the trait ref.
+    ///
+    /// The `async` modifier is lowered directly into a different trait for now.
+    pub modifiers: TraitBoundModifier,
+
     /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
     pub trait_ref: TraitRef<'hir>,
 
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 58916d05865..ffe519b0e7d 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -905,7 +905,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
             try_visit!(visitor.visit_array_length(length));
         }
         TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
-            for (bound, _modifier) in bounds {
+            for bound in bounds {
                 try_visit!(visitor.visit_poly_trait_ref(bound));
             }
             try_visit!(visitor.visit_lifetime(lifetime));
@@ -1160,7 +1160,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(
     bound: &'v GenericBound<'v>,
 ) -> V::Result {
     match *bound {
-        GenericBound::Trait(ref typ, _modifier) => visitor.visit_poly_trait_ref(typ),
+        GenericBound::Trait(ref typ) => visitor.visit_poly_trait_ref(typ),
         GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
         GenericBound::Use(args, _) => {
             walk_list!(visitor, visit_precise_capturing_arg, args);
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 4429f6346e8..94da3d4ea84 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -61,9 +61,9 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
         Some(true) => (),
         Some(false) | None => {
             tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
-                lint.primary_message(
-                    "use of calling convention not supported on this target on function pointer",
-                );
+                lint.primary_message(format!(
+                    "the calling convention {abi} is not supported on this target"
+                ));
             });
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3079fd71b0c..607068f162a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -829,7 +829,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
 
 fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
     match ty.kind {
-        hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments {
+        hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
             [s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
             _ => false,
         },
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 6d30f7c7b9d..a87b29b3093 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -866,7 +866,7 @@ impl<'tcx> ItemCtxt<'tcx> {
     #[instrument(level = "trace", skip(self))]
     fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
         match b {
-            hir::GenericBound::Trait(poly_trait_ref, _) => {
+            hir::GenericBound::Trait(poly_trait_ref) => {
                 let trait_ref = &poly_trait_ref.trait_ref;
                 if let Some(trait_did) = trait_ref.trait_def_id() {
                     self.tcx.trait_may_define_assoc_item(trait_did, assoc_name)
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index c8852a3a369..cb7f0901c7e 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -644,7 +644,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 debug!(?bounds, ?lifetime, "TraitObject");
                 let scope = Scope::TraitRefBoundary { s: self.scope };
                 self.with(scope, |this| {
-                    for (bound, _) in bounds {
+                    for bound in bounds {
                         this.visit_poly_trait_ref_inner(
                             bound,
                             NonLifetimeBinderAllowed::Deny("trait object types"),
@@ -1918,7 +1918,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                                 return None;
                             }
                             predicate.bounds.iter().find_map(|bound| {
-                                let hir::GenericBound::Trait(trait_, _) = bound else {
+                                let hir::GenericBound::Trait(trait_) = bound else {
                                     return None;
                                 };
                                 BoundVarContext::supertrait_hrtb_vars(
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 45cd46e3df2..8f7ca089c91 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -44,10 +44,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
         let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
             for hir_bound in hir_bounds {
-                let hir::GenericBound::Trait(ptr, modifier) = hir_bound else {
+                let hir::GenericBound::Trait(ptr) = hir_bound else {
                     continue;
                 };
-                match modifier {
+                match ptr.modifiers {
                     hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
                     hir::TraitBoundModifier::Negative => {
                         if let Some(sized_def_id) = sized_def_id
@@ -156,8 +156,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     {
         for hir_bound in hir_bounds {
             match hir_bound {
-                hir::GenericBound::Trait(poly_trait_ref, modifier) => {
-                    let (constness, polarity) = match modifier {
+                hir::GenericBound::Trait(poly_trait_ref) => {
+                    let (constness, polarity) = match poly_trait_ref.modifiers {
                         hir::TraitBoundModifier::Const => {
                             (ty::BoundConstness::Const, ty::PredicatePolarity::Positive)
                         }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 394a263fbb5..98822eec2ac 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         span: Span,
         hir_id: hir::HirId,
-        hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
+        hir_trait_bounds: &[hir::PolyTraitRef<'tcx>],
         lifetime: &hir::Lifetime,
         representation: DynKind,
     ) -> Ty<'tcx> {
@@ -39,8 +39,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let mut bounds = Bounds::default();
         let mut potential_assoc_types = Vec::new();
         let dummy_self = self.tcx().types.trait_object_dummy_self;
-        for (trait_bound, modifier) in hir_trait_bounds.iter().rev() {
-            if *modifier == hir::TraitBoundModifier::Maybe {
+        for trait_bound in hir_trait_bounds.iter().rev() {
+            // FIXME: This doesn't handle `? const`.
+            if trait_bound.modifiers == hir::TraitBoundModifier::Maybe {
                 continue;
             }
             if let GenericArgCountResult {
@@ -263,7 +264,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let args = tcx.mk_args(&args);
 
                 let span = i.bottom().1;
-                let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| {
+                let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
                     hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
                         && hir_bound.span.contains(span)
                 });
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index a735b8cc2a4..01768c89cca 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -718,7 +718,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
         potential_assoc_types: Vec<usize>,
-        trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)],
+        trait_bounds: &[hir::PolyTraitRef<'_>],
     ) {
         if associated_types.values().all(|v| v.is_empty()) {
             return;
@@ -764,12 +764,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // related to issue #91997, turbofishes added only when in an expr or pat
         let mut in_expr_or_pat = false;
         if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
-            let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.0.trait_ref.hir_ref_id));
+            let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
             in_expr_or_pat = match grandparent {
                 hir::Node::Expr(_) | hir::Node::Pat(_) => true,
                 _ => false,
             };
-            match bound.0.trait_ref.path.segments {
+            match bound.trait_ref.path.segments {
                 // FIXME: `trait_ref.path.span` can point to a full path with multiple
                 // segments, even though `trait_ref.path.segments` is of length `1`. Work
                 // around that bug here, even though it should be fixed elsewhere.
@@ -810,7 +810,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // and we can then use their span to indicate this to the user.
         let bound_names = trait_bounds
             .iter()
-            .filter_map(|(poly_trait_ref, _)| {
+            .filter_map(|poly_trait_ref| {
                 let path = poly_trait_ref.trait_ref.path.segments.last()?;
                 let args = path.args?;
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 11c0450bfe2..fd49e7e4439 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -50,7 +50,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 .ok()
                 .is_some_and(|s| s.trim_end().ends_with('<'));
 
-        let is_global = poly_trait_ref.0.trait_ref.path.is_global();
+        let is_global = poly_trait_ref.trait_ref.path.is_global();
 
         let mut sugg = vec![(
             self_ty.span.shrink_to_lo(),
@@ -211,7 +211,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // Check if trait object is safe for suggesting dynamic dispatch.
         let is_dyn_compatible = match self_ty.kind {
             hir::TyKind::TraitObject(objects, ..) => {
-                objects.iter().all(|(o, _)| match o.trait_ref.path.res {
+                objects.iter().all(|o| match o.trait_ref.path.res {
                     Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
                     _ => false,
                 })
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 9fe6a8ee342..9ebfd4f15ab 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -301,16 +301,13 @@ impl<'a> State<'a> {
                     self.word_space("dyn");
                 }
                 let mut first = true;
-                for (bound, modifier) in bounds {
+                for bound in bounds {
                     if first {
                         first = false;
                     } else {
                         self.nbsp();
                         self.word_space("+");
                     }
-                    if *modifier == TraitBoundModifier::Maybe {
-                        self.word("?");
-                    }
                     self.print_poly_trait_ref(bound);
                 }
                 if !lifetime.is_elided() {
@@ -679,6 +676,10 @@ impl<'a> State<'a> {
     }
 
     fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) {
+        // FIXME: This isn't correct!
+        if t.modifiers == TraitBoundModifier::Maybe {
+            self.word("?");
+        }
         self.print_formal_generic_params(t.bound_generic_params);
         self.print_trait_ref(&t.trait_ref);
     }
@@ -2077,10 +2078,7 @@ impl<'a> State<'a> {
             }
 
             match bound {
-                GenericBound::Trait(tref, modifier) => {
-                    if modifier == &TraitBoundModifier::Maybe {
-                        self.word("?");
-                    }
+                GenericBound::Trait(tref) => {
                     self.print_poly_trait_ref(tref);
                 }
                 GenericBound::Outlives(lt) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 1df4d32f3cb..3e9e5326156 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -849,7 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             hir::FnRetTy::Return(hir_ty) => {
                 if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind
                     // FIXME: account for RPITIT.
-                    && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
+                    && let [hir::GenericBound::Trait(trait_ref)] = op_ty.bounds
                     && let Some(hir::PathSegment { args: Some(generic_args), .. }) =
                         trait_ref.trait_ref.path.segments.last()
                     && let [constraint] = generic_args.constraints
@@ -1035,7 +1035,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // extract all bounds from the source code using their spans
         let all_matching_bounds_strs = predicates_from_where
             .filter_map(|bound| match bound {
-                GenericBound::Trait(_, _) => {
+                GenericBound::Trait(_) => {
                     self.tcx.sess.source_map().span_to_snippet(bound.span()).ok()
                 }
                 _ => None,
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index cb8b1df2c6e..1b65dc8214c 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -199,6 +199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self_ty, segment, span, call_expr, self_expr, &pick, args,
         );
 
+        // NOTE: on the failure path, we also record the possibly-used trait methods
+        // since an unused import warning is kinda distracting from the method error.
         for &import_id in &pick.import_ids {
             debug!("used_trait_import: {:?}", import_id);
             self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 4f726f3ed38..05c8912aec1 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -191,6 +191,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Expectation<'tcx>,
         trait_missing_method: bool,
     ) -> ErrorGuaranteed {
+        // NOTE: Reporting a method error should also suppress any unused trait errors,
+        // since the method error is very possibly the reason why the trait wasn't used.
+        for &import_id in
+            self.tcx.in_scope_traits(call_id).into_iter().flatten().flat_map(|c| &c.import_ids)
+        {
+            self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
+        }
+
         let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
             hir::Node::Expr(&hir::Expr {
                 kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml
index 07ee81788ce..a7c2a1804dd 100644
--- a/compiler/rustc_index_macros/Cargo.toml
+++ b/compiler/rustc_index_macros/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 proc-macro = true
 
 [dependencies]
-syn = { version = "2.0.9", features = ["full"] }
+syn = { version = "2.0.9", features = ["full", "extra-traits"] }
 proc-macro2 = "1"
 quote = "1"
 
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index c0a01b0065e..5a3666dcbd4 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -112,10 +112,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
 
     fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
         let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
-        for (bound, modifier) in &bounds[..] {
+        for bound in &bounds[..] {
             let def_id = bound.trait_ref.trait_def_id();
             if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop))
-                && *modifier != hir::TraitBoundModifier::Maybe
+                // FIXME: ?Drop is not a thing.
+                && bound.modifiers != hir::TraitBoundModifier::Maybe
             {
                 let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
                 cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 23dc5214fe2..da603df9a9a 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3859,7 +3859,7 @@ declare_lint! {
     /// This will produce:
     ///
     /// ```text
-    /// warning: use of calling convention not supported on this target on function pointer
+    /// warning: the calling convention `"stdcall"` is not supported on this target
     ///   --> $DIR/unsupported.rs:34:15
     ///    |
     /// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 354ca746b46..4f408ee1574 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -192,7 +192,8 @@ fn suggest_changing_unsized_bound(
             .iter()
             .enumerate()
             .filter(|(_, bound)| {
-                if let hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe) = bound
+                if let hir::GenericBound::Trait(poly) = bound
+                    && poly.modifiers == hir::TraitBoundModifier::Maybe
                     && poly.trait_ref.trait_def_id() == def_id
                 {
                     true
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index f32307f6ed4..a9384501547 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> {
             && let Some(poly) = bounds
                 .iter()
                 .filter_map(|bound| match bound {
-                    ast::GenericBound::Trait(poly, _) => Some(poly),
+                    ast::GenericBound::Trait(poly) => Some(poly),
                     _ => None,
                 })
                 .last()
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 162ff3b94de..2f19a9b6b20 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -948,8 +948,8 @@ impl<'a> Parser<'a> {
             {
                 return Ok((false, seg.ident, seg.args.as_deref().cloned()));
             } else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
-                && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] =
-                    bounds.as_slice()
+                && let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice()
+                && trait_ref.modifiers == ast::TraitBoundModifiers::NONE
                 && let [seg] = trait_ref.trait_ref.path.segments.as_slice()
             {
                 return Ok((true, seg.ident, seg.args.as_deref().cloned()));
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 48d29e84b2c..c561ea3823d 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -420,8 +420,13 @@ impl<'a> Parser<'a> {
         lo: Span,
         parse_plus: bool,
     ) -> PResult<'a, TyKind> {
-        let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
-        let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)];
+        let poly_trait_ref = PolyTraitRef::new(
+            generic_params,
+            path,
+            TraitBoundModifiers::NONE,
+            lo.to(self.prev_token.span),
+        );
+        let bounds = vec![GenericBound::Trait(poly_trait_ref)];
         self.parse_remaining_bounds(bounds, parse_plus)
     }
 
@@ -1117,8 +1122,9 @@ impl<'a> Parser<'a> {
             }
         }
 
-        let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span));
-        Ok(GenericBound::Trait(poly_trait, modifiers))
+        let poly_trait =
+            PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
+        Ok(GenericBound::Trait(poly_trait))
     }
 
     // recovers a `Fn(..)` parenthesized-style path from `fn(..)`
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index e7ef4385baf..1716f417969 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -473,19 +473,19 @@ impl<'a> Parser<'a> {
             }
 
             pos = peek_pos;
-            description = format!("expected `'}}'`, found `{maybe:?}`");
+            description = format!("expected `}}`, found `{}`", maybe.escape_debug());
         } else {
-            description = "expected `'}'` but string was terminated".to_owned();
+            description = "expected `}` but string was terminated".to_owned();
             // point at closing `"`
             pos = self.input.len() - if self.append_newline { 1 } else { 0 };
         }
 
         let pos = self.to_span_index(pos);
 
-        let label = "expected `'}'`".to_owned();
+        let label = "expected `}`".to_owned();
         let (note, secondary_label) = if arg.format.fill == Some('}') {
             (
-                Some("the character `'}'` is interpreted as a fill character because of the `:` that precedes it".to_owned()),
+                Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()),
                 arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
             )
         } else {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index aced05ca351..50fbdcaf9dc 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     continue;
                 };
                 for bound in bounds {
-                    let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound
-                    else {
+                    let ast::GenericBound::Trait(trait_ref) = bound else {
                         continue;
                     };
-                    if base_error.span == trait_ref.span {
+                    if trait_ref.modifiers == ast::TraitBoundModifiers::NONE
+                        && base_error.span == trait_ref.span
+                    {
                         err.span_suggestion_verbose(
                             constraint.ident.span.between(trait_ref.span),
                             "you might have meant to write a path instead of an associated type bound",
@@ -837,7 +838,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 );
                 if bounds.iter().all(|bound| match bound {
                     ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
-                    ast::GenericBound::Trait(tr, _) => tr.span == base_error.span,
+                    ast::GenericBound::Trait(tr) => tr.span == base_error.span,
                 }) {
                     let mut sugg = vec![];
                     if base_error.span != start_span {
@@ -1210,7 +1211,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let param = generics.params.iter().find_map(|param| {
             // Only consider type params with exactly one trait bound.
             if let [bound] = &*param.bounds
-                && let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound
+                && let ast::GenericBound::Trait(tref) = bound
+                && tref.modifiers == ast::TraitBoundModifiers::NONE
                 && tref.span == span
                 && param.ident.span.eq_ctxt(span)
             {
@@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             }
             if let (
                 [ast::PathSegment { args: None, .. }],
-                [ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)],
+                [ast::GenericBound::Trait(poly_trait_ref)],
             ) = (&type_param_path.segments[..], &bounds[..])
+                && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE
             {
                 if let [ast::PathSegment { ident, args: None, .. }] =
                     &poly_trait_ref.trait_ref.path.segments[..]
@@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                             && bounded_ty.id == binder
                         {
                             for bound in bounds {
-                                if let ast::GenericBound::Trait(poly_trait_ref, _) = bound
+                                if let ast::GenericBound::Trait(poly_trait_ref) = bound
                                     && let span = poly_trait_ref
                                         .span
                                         .with_hi(poly_trait_ref.trait_ref.path.span.lo())
@@ -3233,7 +3236,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                             let mut lt_finder =
                                 LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
                             for bound in arg_refs {
-                                if let ast::GenericBound::Trait(trait_ref, _) = bound {
+                                if let ast::GenericBound::Trait(trait_ref) = bound {
                                     lt_finder.visit_trait_ref(&trait_ref.trait_ref);
                                 }
                             }
@@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate(
         span: DUMMY_SP,
         bound_generic_params: ThinVec::new(),
         bounded_ty: ast::ptr::P(ty.clone()),
-        bounds: vec![ast::GenericBound::Trait(
-            ast::PolyTraitRef {
-                bound_generic_params: ThinVec::new(),
-                trait_ref: ast::TraitRef {
-                    path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
-                    ref_id: DUMMY_NODE_ID,
-                },
-                span: DUMMY_SP,
+        bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
+            bound_generic_params: ThinVec::new(),
+            modifiers: ast::TraitBoundModifiers::NONE,
+            trait_ref: ast::TraitRef {
+                path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
+                ref_id: DUMMY_NODE_ID,
             },
-            ast::TraitBoundModifiers::NONE,
-        )],
+            span: DUMMY_SP,
+        })],
     };
 
     Some(new_where_bound_predicate)
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
index 7a44c2ad661..2ecd28f4868 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
@@ -86,7 +86,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
             }
 
             hir::TyKind::TraitObject(bounds, ..) => {
-                for (bound, _) in bounds {
+                for bound in bounds {
                     self.current_index.shift_in(1);
                     self.visit_poly_trait_ref(bound);
                     self.current_index.shift_out(1);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index a6ecd1cc987..8541621b23b 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -599,7 +599,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
             _,
         ) = t.kind
         {
-            for (ptr, _) in poly_trait_refs {
+            for ptr in poly_trait_refs {
                 if Some(self.1) == ptr.trait_ref.trait_def_id() {
                     self.0.push(ptr.span);
                 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index cf0ab630f2e..62204f63dd0 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -894,7 +894,9 @@ fn foo(&self) -> Self::T { String::new() }
         // FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
 
         let trait_bounds = bounds.iter().filter_map(|bound| match bound {
-            hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr),
+            hir::GenericBound::Trait(ptr) if ptr.modifiers == hir::TraitBoundModifier::None => {
+                Some(ptr)
+            }
             _ => None,
         });
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index 709b6eb18e3..fc2d0ba36f0 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -740,9 +740,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
                         left, right,
                     ) {
-                        (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr))
+                        // FIXME: Suspicious
+                        (hir::GenericBound::Trait(tl), hir::GenericBound::Trait(tr))
                             if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
-                                && ml == mr =>
+                                && tl.modifiers == tr.modifiers =>
                         {
                             true
                         }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index becc1acfb66..ba57909fc23 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -439,7 +439,7 @@ pub fn report_dyn_incompatibility<'tcx>(
         if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
             // Do not suggest `impl Trait` when dealing with things like super-traits.
             err.span_suggestion_verbose(
-                ty.span.until(trait_ref.0.span),
+                ty.span.until(trait_ref.span),
                 "consider using an opaque type instead",
                 "impl ",
                 Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 87834c329e1..733baaa99e5 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3074,11 +3074,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     match ty.kind {
                         hir::TyKind::TraitObject(traits, _, _) => {
                             let (span, kw) = match traits {
-                                [(first, _), ..] if first.span.lo() == ty.span.lo() => {
+                                [first, ..] if first.span.lo() == ty.span.lo() => {
                                     // Missing `dyn` in front of trait object.
                                     (ty.span.shrink_to_lo(), "dyn ")
                                 }
-                                [(first, _), ..] => (ty.span.until(first.span), ""),
+                                [first, ..] => (ty.span.until(first.span), ""),
                                 [] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
                             };
                             let needs_parens = traits.len() != 1;
@@ -5162,7 +5162,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
     let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
 
     let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
-    let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
+    let [hir::GenericBound::Trait(trait_ref)] = future.bounds else {
         // `async fn` should always lower to a single bound... but don't ICE.
         return None;
     };
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index 45e7de942fb..364a13b3a75 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -125,7 +125,7 @@ fn sized_trait_bound_spans<'tcx>(
     bounds: hir::GenericBounds<'tcx>,
 ) -> impl 'tcx + Iterator<Item = Span> {
     bounds.iter().filter_map(move |b| match b {
-        hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None)
+        hir::GenericBound::Trait(trait_ref)
             if trait_has_sized_self(
                 tcx,
                 trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index b5e5b58f705..6a4f2af10ef 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1107,17 +1107,19 @@ pub(crate) mod builtin {
     ///
     /// If the named environment variable is present at compile time, this will
     /// expand into an expression of type `Option<&'static str>` whose value is
-    /// `Some` of the value of the environment variable. If the environment
-    /// variable is not present, then this will expand to `None`. See
-    /// [`Option<T>`][Option] for more information on this type.  Use
-    /// [`std::env::var`] instead if you want to read the value at runtime.
+    /// `Some` of the value of the environment variable (a compilation error
+    /// will be emitted if the environment variable is not a valid Unicode
+    /// string). If the environment variable is not present, then this will
+    /// expand to `None`. See [`Option<T>`][Option] for more information on this
+    /// type.  Use [`std::env::var`] instead if you want to read the value at
+    /// runtime.
     ///
     /// [`std::env::var`]: ../std/env/fn.var.html
     ///
-    /// A compile time error is never emitted when using this macro regardless
-    /// of whether the environment variable is present or not.
-    /// To emit a compile error if the environment variable is not present,
-    /// use the [`env!`] macro instead.
+    /// A compile time error is only emitted when using this macro if the
+    /// environment variable exists and is not a valid Unicode string. To also
+    /// emit a compile error if the environment variable is not present, use the
+    /// [`env!`] macro instead.
     ///
     /// # Examples
     ///
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index c9af7f13e46..0b0449d6174 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -63,21 +63,22 @@ impl<T: ?Sized> *const T {
         self as _
     }
 
-    /// Uses the pointer value in a new pointer of another type.
+    /// Uses the address value in a new pointer of another type.
     ///
-    /// In case `meta` is a (fat) pointer to an unsized type, this operation
-    /// will ignore the pointer part, whereas for (thin) pointers to sized
-    /// types, this has the same effect as a simple cast.
+    /// This operation will ignore the address part of its `meta` operand and discard existing
+    /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
+    /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address
+    /// with new metadata such as slice lengths or `dyn`-vtable.
     ///
-    /// The resulting pointer will have provenance of `self`, i.e., for a fat
-    /// pointer, this operation is semantically the same as creating a new
-    /// fat pointer with the data pointer value of `self` but the metadata of
-    /// `meta`.
+    /// The resulting pointer will have provenance of `self`. This operation is semantically the
+    /// same as creating a new pointer with the data pointer value of `self` but the metadata of
+    /// `meta`, being fat or thin depending on the `meta` operand.
     ///
     /// # Examples
     ///
-    /// This function is primarily useful for allowing byte-wise pointer
-    /// arithmetic on potentially fat pointers:
+    /// This function is primarily useful for enabling pointer arithmetic on potentially fat
+    /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then
+    /// recombined with its own original metadata.
     ///
     /// ```
     /// #![feature(set_ptr_value)]
@@ -91,6 +92,26 @@ impl<T: ?Sized> *const T {
     ///     println!("{:?}", &*ptr); // will print "3"
     /// }
     /// ```
+    ///
+    /// # *Incorrect* usage
+    ///
+    /// The provenance from pointers is *not* combined. The result must only be used to refer to the
+    /// address allowed by `self`.
+    ///
+    /// ```rust,no_run
+    /// #![feature(set_ptr_value)]
+    /// let x = 0u32;
+    /// let y = 1u32;
+    ///
+    /// let x = (&x) as *const u32;
+    /// let y = (&y) as *const u32;
+    ///
+    /// let offset = (x as usize - y as usize) / 4;
+    /// let bad = x.wrapping_add(offset).with_metadata_of(y);
+    ///
+    /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
+    /// println!("{:?}", unsafe { &*bad });
+    /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
     #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index ced6cb7d520..8b61da74d02 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -45,21 +45,22 @@ impl<T: ?Sized> *mut T {
         self as _
     }
 
-    /// Uses the pointer value in a new pointer of another type.
+    /// Uses the address value in a new pointer of another type.
     ///
-    /// In case `meta` is a (fat) pointer to an unsized type, this operation
-    /// will ignore the pointer part, whereas for (thin) pointers to sized
-    /// types, this has the same effect as a simple cast.
+    /// This operation will ignore the address part of its `meta` operand and discard existing
+    /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
+    /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address
+    /// with new metadata such as slice lengths or `dyn`-vtable.
     ///
-    /// The resulting pointer will have provenance of `self`, i.e., for a fat
-    /// pointer, this operation is semantically the same as creating a new
-    /// fat pointer with the data pointer value of `self` but the metadata of
-    /// `meta`.
+    /// The resulting pointer will have provenance of `self`. This operation is semantically the
+    /// same as creating a new pointer with the data pointer value of `self` but the metadata of
+    /// `meta`, being fat or thin depending on the `meta` operand.
     ///
     /// # Examples
     ///
-    /// This function is primarily useful for allowing byte-wise pointer
-    /// arithmetic on potentially fat pointers:
+    /// This function is primarily useful for enabling pointer arithmetic on potentially fat
+    /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then
+    /// recombined with its own original metadata.
     ///
     /// ```
     /// #![feature(set_ptr_value)]
@@ -73,6 +74,25 @@ impl<T: ?Sized> *mut T {
     ///     println!("{:?}", &*ptr); // will print "3"
     /// }
     /// ```
+    ///
+    /// # *Incorrect* usage
+    ///
+    /// The provenance from pointers is *not* combined. The result must only be used to refer to the
+    /// address allowed by `self`.
+    ///
+    /// ```rust,no_run
+    /// #![feature(set_ptr_value)]
+    /// let mut x = 0u32;
+    /// let mut y = 1u32;
+    ///
+    /// let x = (&mut x) as *mut u32;
+    /// let y = (&mut y) as *mut u32;
+    ///
+    /// let offset = (x as usize - y as usize) / 4;
+    /// let bad = x.wrapping_add(offset).with_metadata_of(y);
+    ///
+    /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
+    /// println!("{:?}", unsafe { &*bad });
     #[unstable(feature = "set_ptr_value", issue = "75091")]
     #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index fa73733360c..1ddad917b78 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -214,15 +214,15 @@ fn clean_generic_bound<'tcx>(
 ) -> Option<GenericBound> {
     Some(match *bound {
         hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
-        hir::GenericBound::Trait(ref t, modifier) => {
+        hir::GenericBound::Trait(ref t) => {
             // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
-            if modifier == hir::TraitBoundModifier::MaybeConst
+            if t.modifiers == hir::TraitBoundModifier::MaybeConst
                 && cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap())
             {
                 return None;
             }
 
-            GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier)
+            GenericBound::TraitBound(clean_poly_trait_ref(t, cx), t.modifiers)
         }
         hir::GenericBound::Use(args, ..) => {
             GenericBound::Use(args.iter().map(|arg| arg.name()).collect())
@@ -1833,7 +1833,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
         }
         TyKind::Path(_) => clean_qpath(ty, cx),
         TyKind::TraitObject(bounds, lifetime, _) => {
-            let bounds = bounds.iter().map(|(bound, _)| clean_poly_trait_ref(bound, cx)).collect();
+            let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
             let lifetime =
                 if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None };
             DynTrait(bounds, lifetime)
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index d5bc2a93fa8..7b2a5eb3d63 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -643,8 +643,7 @@ fn run_test(
     } else {
         cmd = Command::new(&output_file);
         if doctest.is_multiple_tests {
-            cmd.arg("*doctest-bin-path");
-            cmd.arg(&output_file);
+            cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file);
         }
     }
     if let Some(run_directory) = &rustdoc_options.test_run_directory {
diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs
index 942ec8d9936..093755103f3 100644
--- a/src/librustdoc/doctest/runner.rs
+++ b/src/librustdoc/doctest/runner.rs
@@ -112,8 +112,7 @@ mod __doctest_mod {{
     use std::path::PathBuf;
 
     pub static BINARY_PATH: OnceLock<PathBuf> = OnceLock::new();
-    pub const RUN_OPTION: &str = \"*doctest-inner-test\";
-    pub const BIN_OPTION: &str = \"*doctest-bin-path\";
+    pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\";
 
     #[allow(unused)]
     pub fn doctest_path() -> Option<&'static PathBuf> {{
@@ -123,8 +122,8 @@ mod __doctest_mod {{
     #[allow(unused)]
     pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{
         let out = std::process::Command::new(bin)
-            .arg(self::RUN_OPTION)
-            .arg(test_nb.to_string())
+            .env(self::RUN_OPTION, test_nb.to_string())
+            .args(std::env::args().skip(1).collect::<Vec<_>>())
             .output()
             .expect(\"failed to run command\");
         if !out.status.success() {{
@@ -138,36 +137,27 @@ mod __doctest_mod {{
 #[rustc_main]
 fn main() -> std::process::ExitCode {{
 const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}];
-let bin_marker = std::ffi::OsStr::new(__doctest_mod::BIN_OPTION);
 let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION);
 let test_args = &[{test_args}];
+const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\";
 
-let mut args = std::env::args_os().skip(1);
-while let Some(arg) = args.next() {{
-    if arg == bin_marker {{
-        let Some(binary) = args.next() else {{
-            panic!(\"missing argument after `{{}}`\", __doctest_mod::BIN_OPTION);
-        }};
-        if crate::__doctest_mod::BINARY_PATH.set(binary.into()).is_err() {{
-            panic!(\"`{{}}` option was used more than once\", bin_marker.to_string_lossy());
-        }}
-        return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None));
-    }} else if arg == test_marker {{
-        let Some(nb_test) = args.next() else {{
-            panic!(\"missing argument after `{{}}`\", __doctest_mod::RUN_OPTION);
-        }};
-        if let Some(nb_test) = nb_test.to_str().and_then(|nb| nb.parse::<usize>().ok()) {{
-            if let Some(test) = TESTS.get(nb_test) {{
-                if let test::StaticTestFn(f) = test.testfn {{
-                    return std::process::Termination::report(f());
-                }}
+if let Ok(binary) = std::env::var(ENV_BIN) {{
+    let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into());
+    unsafe {{ std::env::remove_var(ENV_BIN); }}
+    return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None));
+}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{
+    if let Ok(nb_test) = nb_test.parse::<usize>() {{
+        if let Some(test) = TESTS.get(nb_test) {{
+            if let test::StaticTestFn(f) = test.testfn {{
+                return std::process::Termination::report(f());
             }}
         }}
-        panic!(\"Unexpected value after `{{}}`\", __doctest_mod::RUN_OPTION);
     }}
+    panic!(\"Unexpected value for `{{}}`\", __doctest_mod::RUN_OPTION);
 }}
 
-eprintln!(\"WARNING: No argument provided so doctests will be run in the same process\");
+eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \
+the same process\");
 std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None))
 }}",
             nb_tests = self.nb_tests,
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 5f349d78053..590d9afd1b4 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -242,7 +242,8 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
     bounds
         .iter()
         .filter_map(|bound| {
-            if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
+            if let GenericBound::Trait(poly_trait) = bound
+                && let TraitBoundModifier::None = poly_trait.modifiers
                 && let [.., path] = poly_trait.trait_ref.path.segments
                 && poly_trait.bound_generic_params.is_empty()
                 && let Some(trait_def_id) = path.res.opt_def_id()
@@ -307,7 +308,8 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
     // This involves some extra logic when generic arguments are present, since
     // simply comparing trait `DefId`s won't be enough. We also need to compare the generics.
     for (index, bound) in bounds.iter().enumerate() {
-        if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
+        if let GenericBound::Trait(poly_trait) = bound
+            && let TraitBoundModifier::None = poly_trait.modifiers
             && let [.., path] = poly_trait.trait_ref.path.segments
             && let implied_args = path.args.map_or([].as_slice(), |a| a.args)
             && let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 311bbce14bd..035ee40348c 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -310,7 +310,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
     if let ty::Alias(_, alias_ty) = ty.kind()
         && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
         && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
-        && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
+        && let [GenericBound::Trait(trait_ref)] = &opaque.bounds
         && let Some(segment) = trait_ref.trait_ref.path.segments.last()
         && let Some(generic_args) = segment.args
         && let [constraint] = generic_args.constraints
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index ec28671a061..a7c48eb216a 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -163,7 +163,7 @@ fn check_fn_inner<'tcx>(
                 if visitor.lts.iter().any(|lt| matches!(lt.res, LifetimeName::Param(_))) {
                     return;
                 }
-                if let GenericBound::Trait(ref trait_ref, _) = *bound {
+                if let GenericBound::Trait(ref trait_ref) = *bound {
                     let params = &trait_ref
                         .trait_ref
                         .path
@@ -438,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
                 if !lt.is_elided() {
                     self.unelided_trait_object_lifetime = true;
                 }
-                for (bound, _) in bounds {
+                for bound in bounds {
                     self.visit_poly_trait_ref(bound);
                 }
             },
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 81115cffdca..67255c1af79 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -107,7 +107,7 @@ fn future_trait_ref<'tcx>(
 ) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
     if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
         && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
-            if let GenericBound::Trait(poly, _) = bound {
+            if let GenericBound::Trait(poly) = bound {
                 Some(&poly.trait_ref)
             } else {
                 None
diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
index bb44ff37b20..a56024f08d5 100644
--- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
@@ -40,7 +40,6 @@ struct Bound<'tcx> {
     ident: Ident,
 
     trait_bound: &'tcx PolyTraitRef<'tcx>,
-    modifier: TraitBoundModifier,
 
     predicate_pos: usize,
     bound_pos: usize,
@@ -65,11 +64,10 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator<Item
                     .iter()
                     .enumerate()
                     .filter_map(move |(bound_pos, bound)| match bound {
-                        &GenericBound::Trait(ref trait_bound, modifier) => Some(Bound {
+                        &GenericBound::Trait(ref trait_bound) => Some(Bound {
                             param,
                             ident,
                             trait_bound,
-                            modifier,
                             predicate_pos,
                             bound_pos,
                         }),
@@ -120,13 +118,13 @@ impl LateLintPass<'_> for NeedlessMaybeSized {
         let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)
             .filter(|bound| {
                 bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait)
-                    && bound.modifier == TraitBoundModifier::Maybe
+                    && bound.trait_bound.modifiers == TraitBoundModifier::Maybe
             })
             .map(|bound| (bound.param, bound))
             .collect();
 
         for bound in type_param_bounds(generics) {
-            if bound.modifier == TraitBoundModifier::None
+            if bound.trait_bound.modifiers == TraitBoundModifier::None
                 && let Some(sized_bound) = maybe_sized_params.get(&bound.param)
                 && let Some(path) = path_to_sized_bound(cx, bound.trait_bound)
             {
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 3c3973857e7..38befdee574 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
 
             // Iterate the bounds and add them to our seen hash
             // If we haven't yet seen it, add it to the fixed traits
-            for (bound, _) in bounds {
+            for bound in bounds {
                 let Some(def_id) = bound.trait_ref.trait_def_id() else {
                     continue;
                 };
@@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
             // If the number of unique traits isn't the same as the number of traits in the bounds,
             // there must be 1 or more duplicates
             if bounds.len() != unique_traits.len() {
-                let mut bounds_span = bounds[0].0.span;
+                let mut bounds_span = bounds[0].span;
 
-                for (bound, _) in bounds.iter().skip(1) {
+                for bound in bounds.iter().skip(1) {
                     bounds_span = bounds_span.to(bound.span);
                 }
 
@@ -229,7 +229,8 @@ impl TraitBounds {
     /// this MSRV? See <https://github.com/rust-lang/rust-clippy/issues/8772> for details.
     fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {
         if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE)
-            && let GenericBound::Trait(tr, TraitBoundModifier::Maybe) = bound
+            && let GenericBound::Trait(tr) = bound
+            && let TraitBoundModifier::Maybe = tr.modifiers
         {
             cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id()
         } else {
@@ -375,11 +376,11 @@ impl Default for ComparableTraitRef {
 }
 
 fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> {
-    if let GenericBound::Trait(t, tbm) = bound {
+    if let GenericBound::Trait(t) = bound {
         let trait_path = t.trait_ref.path;
         let trait_span = {
             let path_span = trait_path.span;
-            if let TraitBoundModifier::Maybe = tbm {
+            if let TraitBoundModifier::Maybe = t.modifiers {
                 path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?`
             } else {
                 path_span
@@ -430,7 +431,7 @@ fn rollup_traits(
     let mut repeated_res = false;
 
     let only_comparable_trait_refs = |bound: &GenericBound<'_>| {
-        if let GenericBound::Trait(t, _) = bound {
+        if let GenericBound::Trait(t) = bound {
             Some((into_comparable_trait_ref(&t.trait_ref), t.span))
         } else {
             None
diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
index 2fcfc71a8c7..eb7ffbbe360 100644
--- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
@@ -82,7 +82,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
 // Returns true if given type is `Any` trait.
 fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
     if let TyKind::TraitObject(traits, ..) = t.kind {
-        return traits.iter().any(|(bound, _)| {
+        return traits.iter().any(|bound| {
             if let Some(trait_did) = bound.trait_ref.trait_def_id()
                 && cx.tcx.is_diagnostic_item(sym::Any, trait_did)
             {
diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
index 0b64fddb447..b89bd6a8d05 100644
--- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
@@ -55,7 +55,6 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
             TyKind::TraitObject(param_bounds, _, _) => {
                 let has_lifetime_parameters = param_bounds.iter().any(|bound| {
                     bound
-                        .0
                         .bound_generic_params
                         .iter()
                         .any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 187f7fb4417..0be6dc15a8e 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -786,7 +786,8 @@ pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool {
 }
 
 pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool {
-    eq_path(&l.trait_ref.path, &r.trait_ref.path)
+    l.modifiers == r.modifiers
+        && eq_path(&l.trait_ref.path, &r.trait_ref.path)
         && over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
             eq_generic_param(l, r)
         })
@@ -820,7 +821,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
 pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
     use GenericBound::*;
     match (l, r) {
-        (Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2),
+        (Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2),
         (Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),
         _ => false,
     }
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index a5418ad8384..1ee00a3a4e8 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -759,14 +759,8 @@ pub fn output_testname_unique(
 /// test/revision should reside. Example:
 ///   /path/to/build/host-triple/test/ui/relative/testname.revision.mode/
 pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf {
-    // In run-make tests, constructing a relative path + unique testname causes a double layering
-    // since revisions are not supported, causing unnecessary nesting.
-    if config.mode == Mode::RunMake {
-        output_relative_path(config, &testpaths.relative_dir)
-    } else {
-        output_relative_path(config, &testpaths.relative_dir)
-            .join(output_testname_unique(config, testpaths, revision))
-    }
+    output_relative_path(config, &testpaths.relative_dir)
+        .join(output_testname_unique(config, testpaths, revision))
 }
 
 /// Absolute path to the base filename used as output for the given
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 860d21876de..328b48e04d2 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -235,7 +235,9 @@ try:
         exit(0)
 
     cur_commit = sys.argv[1]
-    cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
+    cur_datetime = datetime.datetime.now(datetime.timezone.utc).strftime(
+        '%Y-%m-%dT%H:%M:%SZ'
+    )
     cur_commit_msg = sys.argv[2]
     save_message_to_path = sys.argv[3]
     github_token = sys.argv[4]
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index 555a9240798..4d684f3c635 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg {
 impl Spanned for ast::GenericBound {
     fn span(&self) -> Span {
         match *self {
-            ast::GenericBound::Trait(ref ptr, _) => ptr.span,
+            ast::GenericBound::Trait(ref ptr) => ptr.span,
             ast::GenericBound::Outlives(ref l) => l.ident.span,
             ast::GenericBound::Use(_, span) => span,
         }
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 10027dc3d69..99b3fe60ee2 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound {
 
     fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
-            ast::GenericBound::Trait(
-                ref poly_trait_ref,
-                ast::TraitBoundModifiers {
+            ast::GenericBound::Trait(ref poly_trait_ref) => {
+                let snippet = context.snippet(self.span());
+                let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
+                let ast::TraitBoundModifiers {
                     constness,
                     asyncness,
                     polarity,
-                },
-            ) => {
-                let snippet = context.snippet(self.span());
-                let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
+                } = poly_trait_ref.modifiers;
                 let mut constness = constness.as_str().to_string();
                 if !constness.is_empty() {
                     constness.push(' ');
diff --git a/tests/run-make/README.md b/tests/run-make/README.md
index 40359903473..9e1eaa881c9 100644
--- a/tests/run-make/README.md
+++ b/tests/run-make/README.md
@@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process:
    structure within `build/<target>/test/run-make/`
 
    ```
-   <test-name>/
+   <test-name>/<test-name>/
        rmake.exe              # recipe binary
        rmake_out/             # sources from test sources copied over
    ```
diff --git a/tests/run-make/non-unicode-env/non_unicode_env.rs b/tests/run-make/non-unicode-env/non_unicode_env.rs
index 865fc937365..3efa4842d94 100644
--- a/tests/run-make/non-unicode-env/non_unicode_env.rs
+++ b/tests/run-make/non-unicode-env/non_unicode_env.rs
@@ -1,3 +1,4 @@
 fn main() {
     let _ = env!("NON_UNICODE_VAR");
+    let _ = option_env!("NON_UNICODE_VAR");
 }
diff --git a/tests/run-make/non-unicode-env/non_unicode_env.stderr b/tests/run-make/non-unicode-env/non_unicode_env.stderr
index c4dcd7b2eb7..1f260ac9c07 100644
--- a/tests/run-make/non-unicode-env/non_unicode_env.stderr
+++ b/tests/run-make/non-unicode-env/non_unicode_env.stderr
@@ -6,5 +6,13 @@ error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string
   |
   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 1 previous error
+error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string
+ --> non_unicode_env.rs:3:13
+  |
+3 |     let _ = option_env!("NON_UNICODE_VAR");
+  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  |
+  = note: this error originates in the macro `option_env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index e8cec632177..1577b68e748 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -178,7 +178,7 @@ struct ErrorWithNonexistentField {
 }
 
 #[derive(Diagnostic)]
-//~^ ERROR invalid format string: expected `'}'`
+//~^ ERROR invalid format string: expected `}`
 #[diag(no_crate_example, code = E0123)]
 struct ErrorMissingClosingBrace {
     #[suggestion(no_crate_suggestion, code = "{name")]
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 97f9896f3a7..ff7af388514 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -184,11 +184,11 @@ error: `name` doesn't refer to a field on this type
 LL |     #[suggestion(no_crate_suggestion, code = "{name}")]
    |                                              ^^^^^^^^
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/diagnostic-derive.rs:180:10
    |
 LL | #[derive(Diagnostic)]
-   |          ^^^^^^^^^^ expected `'}'` in format string
+   |          ^^^^^^^^^^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr
index 00a5b4b2ee1..82908ef88a8 100644
--- a/tests/ui/abi/unsupported.aarch64.stderr
+++ b/tests/ui/abi/unsupported.aarch64.stderr
@@ -1,4 +1,4 @@
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "ptx-kernel" is not supported on this target
   --> $DIR/unsupported.rs:35:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
@@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "aapcs" is not supported on this target
   --> $DIR/unsupported.rs:49:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
@@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "msp430-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:71:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
@@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "avr-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:81:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
@@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
   --> $DIR/unsupported.rs:94:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
@@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "x86-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:116:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
@@ -89,7 +89,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "thiscall" is not supported on this target
   --> $DIR/unsupported.rs:139:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
@@ -104,7 +104,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "stdcall" is not supported on this target
   --> $DIR/unsupported.rs:170:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
@@ -123,7 +123,7 @@ LL | extern "stdcall" {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
   --> $DIR/unsupported.rs:195:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
@@ -132,7 +132,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
   --> $DIR/unsupported.rs:203:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr
index dfb5ceb0c33..39ec5d16fcd 100644
--- a/tests/ui/abi/unsupported.arm.stderr
+++ b/tests/ui/abi/unsupported.arm.stderr
@@ -1,4 +1,4 @@
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "ptx-kernel" is not supported on this target
   --> $DIR/unsupported.rs:35:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
@@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "msp430-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:71:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
@@ -29,7 +29,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "avr-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:81:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
@@ -44,7 +44,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
   --> $DIR/unsupported.rs:94:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
@@ -59,7 +59,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "x86-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:116:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
@@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "thiscall" is not supported on this target
   --> $DIR/unsupported.rs:139:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
@@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "stdcall" is not supported on this target
   --> $DIR/unsupported.rs:170:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
@@ -108,7 +108,7 @@ LL | extern "stdcall" {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
   --> $DIR/unsupported.rs:195:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
@@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
   --> $DIR/unsupported.rs:203:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr
index 6537ce66057..1dc01a66aab 100644
--- a/tests/ui/abi/unsupported.i686.stderr
+++ b/tests/ui/abi/unsupported.i686.stderr
@@ -1,4 +1,4 @@
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "ptx-kernel" is not supported on this target
   --> $DIR/unsupported.rs:35:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
@@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "aapcs" is not supported on this target
   --> $DIR/unsupported.rs:49:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
@@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "msp430-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:71:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
@@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "avr-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:81:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
@@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
   --> $DIR/unsupported.rs:94:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
@@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
   --> $DIR/unsupported.rs:195:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
@@ -83,7 +83,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
   --> $DIR/unsupported.rs:203:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr
index a53f85f28bc..e7d5197feeb 100644
--- a/tests/ui/abi/unsupported.riscv32.stderr
+++ b/tests/ui/abi/unsupported.riscv32.stderr
@@ -1,4 +1,4 @@
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "ptx-kernel" is not supported on this target
   --> $DIR/unsupported.rs:35:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
@@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "aapcs" is not supported on this target
   --> $DIR/unsupported.rs:49:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
@@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "msp430-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:71:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
@@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "avr-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:81:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
@@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "x86-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:116:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
@@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "thiscall" is not supported on this target
   --> $DIR/unsupported.rs:139:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
@@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "stdcall" is not supported on this target
   --> $DIR/unsupported.rs:170:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
@@ -108,7 +108,7 @@ LL | extern "stdcall" {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
   --> $DIR/unsupported.rs:195:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
@@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
   --> $DIR/unsupported.rs:203:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr
index a53f85f28bc..e7d5197feeb 100644
--- a/tests/ui/abi/unsupported.riscv64.stderr
+++ b/tests/ui/abi/unsupported.riscv64.stderr
@@ -1,4 +1,4 @@
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "ptx-kernel" is not supported on this target
   --> $DIR/unsupported.rs:35:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
@@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "aapcs" is not supported on this target
   --> $DIR/unsupported.rs:49:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
@@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "msp430-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:71:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
@@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "avr-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:81:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
@@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "x86-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:116:15
    |
 LL | fn x86_ptr(f: extern "x86-interrupt" fn()) {
@@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "thiscall" is not supported on this target
   --> $DIR/unsupported.rs:139:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
@@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "stdcall" is not supported on this target
   --> $DIR/unsupported.rs:170:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
@@ -108,7 +108,7 @@ LL | extern "stdcall" {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
   --> $DIR/unsupported.rs:195:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
@@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
   --> $DIR/unsupported.rs:203:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr
index 45ba9a6649c..bbca754dd41 100644
--- a/tests/ui/abi/unsupported.x64.stderr
+++ b/tests/ui/abi/unsupported.x64.stderr
@@ -1,4 +1,4 @@
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "ptx-kernel" is not supported on this target
   --> $DIR/unsupported.rs:35:15
    |
 LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) {
@@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "aapcs" is not supported on this target
   --> $DIR/unsupported.rs:49:17
    |
 LL | fn aapcs_ptr(f: extern "aapcs" fn()) {
@@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target
 LL | extern "aapcs" {}
    | ^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "msp430-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:71:18
    |
 LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) {
@@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "avr-interrupt" is not supported on this target
   --> $DIR/unsupported.rs:81:15
    |
 LL | fn avr_ptr(f: extern "avr-interrupt" fn()) {
@@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
 LL | extern "avr-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
   --> $DIR/unsupported.rs:94:17
    |
 LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) {
@@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe
 LL | extern "riscv-interrupt-m" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "thiscall" is not supported on this target
   --> $DIR/unsupported.rs:139:20
    |
 LL | fn thiscall_ptr(f: extern "thiscall" fn()) {
@@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "stdcall" is not supported on this target
   --> $DIR/unsupported.rs:170:19
    |
 LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
@@ -108,7 +108,7 @@ LL | extern "stdcall" {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
   --> $DIR/unsupported.rs:195:21
    |
 LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
@@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) {
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
 
-warning: use of calling convention not supported on this target on function pointer
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
   --> $DIR/unsupported.rs:203:22
    |
 LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) {
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs
index 8d8917fd319..3ca58b28181 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs
@@ -19,8 +19,8 @@ trait ImportantTrait3 {}
 trait ImportantTrait4 {}
 
 #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
-//~^WARN expected `'}'`, found `'!'`
-//~|WARN expected `'}'`, found `'!'`
+//~^WARN expected `}`, found `!`
+//~|WARN expected `}`, found `!`
 //~|WARN unmatched `}` found
 //~|WARN unmatched `}` found
 trait ImportantTrait5 {}
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr
index 932e81ca48e..b4ed06cb63d 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr
@@ -30,7 +30,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
    |
    = help: no format specifier are supported in this position
 
-warning: expected `'}'`, found `'!'`
+warning: expected `}`, found `!`
   --> $DIR/broken_format.rs:21:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
@@ -153,7 +153,7 @@ note: required by a bound in `check_4`
 LL | fn check_4(_: impl ImportantTrait4) {}
    |                    ^^^^^^^^^^^^^^^ required by this bound in `check_4`
 
-warning: expected `'}'`, found `'!'`
+warning: expected `}`, found `!`
   --> $DIR/broken_format.rs:21:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
diff --git a/tests/ui/fmt/closing-brace-as-fill.rs b/tests/ui/fmt/closing-brace-as-fill.rs
index 6ad257f943e..5865ee31c43 100644
--- a/tests/ui/fmt/closing-brace-as-fill.rs
+++ b/tests/ui/fmt/closing-brace-as-fill.rs
@@ -4,5 +4,5 @@
 
 fn main() {
     println!("Hello, world! {0:}<3", 2);
-    //~^ ERROR invalid format string: expected `'}'` but string was terminated
+    //~^ ERROR invalid format string: expected `}` but string was terminated
 }
diff --git a/tests/ui/fmt/closing-brace-as-fill.stderr b/tests/ui/fmt/closing-brace-as-fill.stderr
index 70068fa3aad..aa22beddf45 100644
--- a/tests/ui/fmt/closing-brace-as-fill.stderr
+++ b/tests/ui/fmt/closing-brace-as-fill.stderr
@@ -1,12 +1,12 @@
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/closing-brace-as-fill.rs:6:35
    |
 LL |     println!("Hello, world! {0:}<3", 2);
-   |                                -  ^ expected `'}'` in format string
+   |                                -  ^ expected `}` in format string
    |                                |
    |                                this is not interpreted as a formatting closing brace
    |
-   = note: the character `'}'` is interpreted as a fill character because of the `:` that precedes it
+   = note: the character `}` is interpreted as a fill character because of the `:` that precedes it
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs
index 1f7f0d8f6be..357dd7b10a3 100644
--- a/tests/ui/fmt/format-string-error-2.rs
+++ b/tests/ui/fmt/format-string-error-2.rs
@@ -72,7 +72,7 @@ raw  { \n
 
     // note: `\x7B` is `{`
     println!("\x7B}\u{8} {", 1);
-    //~^ ERROR invalid format string: expected `'}'` but string was terminated
+    //~^ ERROR invalid format string: expected `}` but string was terminated
 
     println!("\x7B}\u8 {", 1);
     //~^ ERROR incorrect unicode escape sequence
diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr
index d5fe4081ac8..a2d142e0bab 100644
--- a/tests/ui/fmt/format-string-error-2.stderr
+++ b/tests/ui/fmt/format-string-error-2.stderr
@@ -9,138 +9,138 @@ help: format of unicode escape sequences uses braces
 LL |     println!("\x7B}\u{8} {", 1);
    |                    ~~~~~
 
-error: invalid format string: expected `'}'`, found `'a'`
+error: invalid format string: expected `}`, found `a`
   --> $DIR/format-string-error-2.rs:5:5
    |
 LL |     format!("{
    |              - because of this opening brace
 LL |     a");
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'b'`
+error: invalid format string: expected `}`, found `b`
   --> $DIR/format-string-error-2.rs:9:5
    |
 LL |     format!("{ \
    |              - because of this opening brace
 LL |                \
 LL |     b");
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'\'`
+error: invalid format string: expected `}`, found `\`
   --> $DIR/format-string-error-2.rs:11:18
    |
 LL |     format!(r#"{ \
-   |                - ^ expected `'}'` in format string
+   |                - ^ expected `}` in format string
    |                |
    |                because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'\'`
+error: invalid format string: expected `}`, found `\`
   --> $DIR/format-string-error-2.rs:15:18
    |
 LL |     format!(r#"{ \n
-   |                - ^ expected `'}'` in format string
+   |                - ^ expected `}` in format string
    |                |
    |                because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'e'`
+error: invalid format string: expected `}`, found `e`
   --> $DIR/format-string-error-2.rs:21:5
    |
 LL |     format!("{ \n
    |              - because of this opening brace
 LL | \n
 LL |     e");
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'a'`
+error: invalid format string: expected `}`, found `a`
   --> $DIR/format-string-error-2.rs:25:5
    |
 LL |     {
    |     - because of this opening brace
 LL |     a");
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'a'`
+error: invalid format string: expected `}`, found `a`
   --> $DIR/format-string-error-2.rs:29:5
    |
 LL |     {
    |     - because of this opening brace
 LL |     a
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'b'`
+error: invalid format string: expected `}`, found `b`
   --> $DIR/format-string-error-2.rs:35:5
    |
 LL |     { \
    |     - because of this opening brace
 LL |         \
 LL |     b");
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'b'`
+error: invalid format string: expected `}`, found `b`
   --> $DIR/format-string-error-2.rs:40:5
    |
 LL |     { \
    |     - because of this opening brace
 LL |         \
 LL |     b \
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'\'`
+error: invalid format string: expected `}`, found `\`
   --> $DIR/format-string-error-2.rs:45:8
    |
 LL | raw  { \
-   |      - ^ expected `'}'` in format string
+   |      - ^ expected `}` in format string
    |      |
    |      because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'\'`
+error: invalid format string: expected `}`, found `\`
   --> $DIR/format-string-error-2.rs:50:8
    |
 LL | raw  { \n
-   |      - ^ expected `'}'` in format string
+   |      - ^ expected `}` in format string
    |      |
    |      because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'e'`
+error: invalid format string: expected `}`, found `e`
   --> $DIR/format-string-error-2.rs:57:5
    |
 LL |   { \n
    |   - because of this opening brace
 LL | \n
 LL |     e");
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'a'`
+error: invalid format string: expected `}`, found `a`
   --> $DIR/format-string-error-2.rs:67:5
    |
 LL |     {
    |     - because of this opening brace
 LL |     asdf}
-   |     ^ expected `'}'` in format string
+   |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
@@ -150,11 +150,11 @@ error: 1 positional argument in format string, but no arguments were given
 LL |     println!("\t{}");
    |                 ^^
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/format-string-error-2.rs:74:27
    |
 LL |     println!("\x7B}\u{8} {", 1);
-   |                          -^ expected `'}'` in format string
+   |                          -^ expected `}` in format string
    |                          |
    |                          because of this opening brace
    |
diff --git a/tests/ui/fmt/format-string-error.rs b/tests/ui/fmt/format-string-error.rs
index 9b436e2c479..cb9449be532 100644
--- a/tests/ui/fmt/format-string-error.rs
+++ b/tests/ui/fmt/format-string-error.rs
@@ -2,7 +2,7 @@
 
 fn main() {
     println!("{");
-    //~^ ERROR invalid format string: expected `'}'` but string was terminated
+    //~^ ERROR invalid format string: expected `}` but string was terminated
     println!("{{}}");
     println!("}");
     //~^ ERROR invalid format string: unmatched `}` found
@@ -13,11 +13,11 @@ fn main() {
     let _ = format!("{a:._$}", a = "", _ = 0);
     //~^ ERROR invalid format string: invalid argument name `_`
     let _ = format!("{");
-    //~^ ERROR invalid format string: expected `'}'` but string was terminated
+    //~^ ERROR invalid format string: expected `}` but string was terminated
     let _ = format!("}");
     //~^ ERROR invalid format string: unmatched `}` found
     let _ = format!("{\\}");
-    //~^ ERROR invalid format string: expected `'}'`, found `'\'`
+    //~^ ERROR invalid format string: expected `}`, found `\`
     let _ = format!("\n\n\n{\n\n\n");
     //~^ ERROR invalid format string
     let _ = format!(r###"
diff --git a/tests/ui/fmt/format-string-error.stderr b/tests/ui/fmt/format-string-error.stderr
index 37a181e6fcb..9d6a91413d0 100644
--- a/tests/ui/fmt/format-string-error.stderr
+++ b/tests/ui/fmt/format-string-error.stderr
@@ -1,8 +1,8 @@
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/format-string-error.rs:4:16
    |
 LL |     println!("{");
-   |               -^ expected `'}'` in format string
+   |               -^ expected `}` in format string
    |               |
    |               because of this opening brace
    |
@@ -40,11 +40,11 @@ LL |     let _ = format!("{a:._$}", a = "", _ = 0);
    |
    = note: argument name cannot be a single underscore
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/format-string-error.rs:15:23
    |
 LL |     let _ = format!("{");
-   |                      -^ expected `'}'` in format string
+   |                      -^ expected `}` in format string
    |                      |
    |                      because of this opening brace
    |
@@ -58,44 +58,44 @@ LL |     let _ = format!("}");
    |
    = note: if you intended to print `}`, you can escape it using `}}`
 
-error: invalid format string: expected `'}'`, found `'\'`
+error: invalid format string: expected `}`, found `\`
   --> $DIR/format-string-error.rs:19:23
    |
 LL |     let _ = format!("{\}");
-   |                      -^ expected `'}'` in format string
+   |                      -^ expected `}` in format string
    |                      |
    |                      because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/format-string-error.rs:21:35
    |
 LL |     let _ = format!("\n\n\n{\n\n\n");
-   |                            -      ^ expected `'}'` in format string
+   |                            -      ^ expected `}` in format string
    |                            |
    |                            because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/format-string-error.rs:27:3
    |
 LL |     {"###);
-   |     -^ expected `'}'` in format string
+   |     -^ expected `}` in format string
    |     |
    |     because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/format-string-error.rs:35:1
    |
 LL |     {
    |     - because of this opening brace
 LL |
 LL | "###);
-   | ^ expected `'}'` in format string
+   | ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
diff --git a/tests/ui/fmt/format-string-wrong-order.rs b/tests/ui/fmt/format-string-wrong-order.rs
index da775be3ffd..891279b97e4 100644
--- a/tests/ui/fmt/format-string-wrong-order.rs
+++ b/tests/ui/fmt/format-string-wrong-order.rs
@@ -7,9 +7,9 @@ fn main() {
     format!("{?:?}", bar);
     //~^ ERROR invalid format string: expected format parameter to occur after `:`
     format!("{??}", bar);
-    //~^ ERROR invalid format string: expected `'}'`, found `'?'`
+    //~^ ERROR invalid format string: expected `}`, found `?`
     format!("{?;bar}");
-    //~^ ERROR invalid format string: expected `'}'`, found `'?'`
+    //~^ ERROR invalid format string: expected `}`, found `?`
     format!("{?:#?}", bar);
     //~^ ERROR invalid format string: expected format parameter to occur after `:`
     format!("Hello {<5:}!", "x");
diff --git a/tests/ui/fmt/format-string-wrong-order.stderr b/tests/ui/fmt/format-string-wrong-order.stderr
index 3ef07720c15..7f017511761 100644
--- a/tests/ui/fmt/format-string-wrong-order.stderr
+++ b/tests/ui/fmt/format-string-wrong-order.stderr
@@ -22,21 +22,21 @@ LL |     format!("{?:?}", bar);
    |
    = note: `?` comes after `:`, try `:?` instead
 
-error: invalid format string: expected `'}'`, found `'?'`
+error: invalid format string: expected `}`, found `?`
   --> $DIR/format-string-wrong-order.rs:9:15
    |
 LL |     format!("{??}", bar);
-   |              -^ expected `'}'` in format string
+   |              -^ expected `}` in format string
    |              |
    |              because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'?'`
+error: invalid format string: expected `}`, found `?`
   --> $DIR/format-string-wrong-order.rs:11:15
    |
 LL |     format!("{?;bar}");
-   |              -^ expected `'}'` in format string
+   |              -^ expected `}` in format string
    |              |
    |              because of this opening brace
    |
diff --git a/tests/ui/fmt/ifmt-bad-arg.rs b/tests/ui/fmt/ifmt-bad-arg.rs
index 68861d7bf3f..e39ffb8fe1b 100644
--- a/tests/ui/fmt/ifmt-bad-arg.rs
+++ b/tests/ui/fmt/ifmt-bad-arg.rs
@@ -48,7 +48,7 @@ fn main() {
 
     // bad syntax of the format string
 
-    format!("{"); //~ ERROR: expected `'}'` but string was terminated
+    format!("{"); //~ ERROR: expected `}` but string was terminated
 
     format!("foo } bar"); //~ ERROR: unmatched `}` found
     format!("foo }"); //~ ERROR: unmatched `}` found
diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr
index 09ce3dca411..4344aee83c2 100644
--- a/tests/ui/fmt/ifmt-bad-arg.stderr
+++ b/tests/ui/fmt/ifmt-bad-arg.stderr
@@ -136,11 +136,11 @@ LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
    |             |
    |             formatting specifier missing
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/ifmt-bad-arg.rs:51:15
    |
 LL |     format!("{");
-   |              -^ expected `'}'` in format string
+   |              -^ expected `}` in format string
    |              |
    |              because of this opening brace
    |
@@ -172,13 +172,13 @@ LL |     format!("foo %s baz", "bar");
    |
    = note: printf formatting is not supported; see the documentation for `std::fmt`
 
-error: invalid format string: expected `'}'`, found `'t'`
+error: invalid format string: expected `}`, found `t`
   --> $DIR/ifmt-bad-arg.rs:75:1
    |
 LL | ninth number: {
    |               - because of this opening brace
 LL | tenth number: {}",
-   | ^ expected `'}'` in format string
+   | ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
diff --git a/tests/ui/fmt/issue-91556.rs b/tests/ui/fmt/issue-91556.rs
index e782e6f9076..fcf8909859c 100644
--- a/tests/ui/fmt/issue-91556.rs
+++ b/tests/ui/fmt/issue-91556.rs
@@ -1,8 +1,8 @@
 fn main() {
   let _ = format!(concat!("{0}π–³π–Ύπ—Œπ—{"), i);
-  //~^ ERROR: invalid format string: expected `'}'` but string was terminated
+  //~^ ERROR: invalid format string: expected `}` but string was terminated
   //~| NOTE: if you intended to print `{`, you can escape it using `{{`
   //~| NOTE: in this expansion of concat!
   //~| NOTE: in this expansion of concat!
-  //~| NOTE: expected `'}'` in format string
+  //~| NOTE: expected `}` in format string
 }
diff --git a/tests/ui/fmt/issue-91556.stderr b/tests/ui/fmt/issue-91556.stderr
index beab3db0d94..52917fb8c42 100644
--- a/tests/ui/fmt/issue-91556.stderr
+++ b/tests/ui/fmt/issue-91556.stderr
@@ -1,8 +1,8 @@
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/issue-91556.rs:2:19
    |
 LL |   let _ = format!(concat!("{0}π–³π–Ύπ—Œπ—{"), i);
-   |                   ^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string
+   |                   ^^^^^^^^^^^^^^^^^^^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
    = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs
index b0c0855a870..0a127b1a0ca 100644
--- a/tests/ui/fmt/respanned-literal-issue-106191.rs
+++ b/tests/ui/fmt/respanned-literal-issue-106191.rs
@@ -4,7 +4,7 @@ extern crate format_string_proc_macro;
 
 fn main() {
     format_string_proc_macro::respan_to_invalid_format_literal!("Β‘");
-    //~^ ERROR invalid format string: expected `'}'` but string was terminated
+    //~^ ERROR invalid format string: expected `}` but string was terminated
     format_args!(r#concat!("Β‘        {"));
-    //~^ ERROR invalid format string: expected `'}'` but string was terminated
+    //~^ ERROR invalid format string: expected `}` but string was terminated
 }
diff --git a/tests/ui/fmt/respanned-literal-issue-106191.stderr b/tests/ui/fmt/respanned-literal-issue-106191.stderr
index 73a3af65a38..17ab29e799b 100644
--- a/tests/ui/fmt/respanned-literal-issue-106191.stderr
+++ b/tests/ui/fmt/respanned-literal-issue-106191.stderr
@@ -1,16 +1,16 @@
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/respanned-literal-issue-106191.rs:6:65
    |
 LL |     format_string_proc_macro::respan_to_invalid_format_literal!("Β‘");
-   |                                                                 ^^^ expected `'}'` in format string
+   |                                                                 ^^^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/respanned-literal-issue-106191.rs:8:18
    |
 LL |     format_args!(r#concat!("Β‘        {"));
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
    = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/macros/issue-51848.stderr b/tests/ui/macros/issue-51848.stderr
index c25bedf37b7..30b64113d73 100644
--- a/tests/ui/macros/issue-51848.stderr
+++ b/tests/ui/macros/issue-51848.stderr
@@ -1,8 +1,8 @@
-error: invalid format string: expected `'}'` but string was terminated
+error: invalid format string: expected `}` but string was terminated
   --> $DIR/issue-51848.rs:6:20
    |
 LL |         println!("{");
-   |                   -^ expected `'}'` in format string
+   |                   -^ expected `}` in format string
    |                   |
    |                   because of this opening brace
 ...
diff --git a/tests/ui/use/unused-trait-with-method-err.rs b/tests/ui/use/unused-trait-with-method-err.rs
new file mode 100644
index 00000000000..37684e1bf81
--- /dev/null
+++ b/tests/ui/use/unused-trait-with-method-err.rs
@@ -0,0 +1,17 @@
+// Test that we don't issue an unused import warning when there's
+// a method lookup error and that trait was possibly applicable.
+
+use foo::Bar;
+
+mod foo {
+    pub trait Bar {
+        fn uwu(&self) {}
+    }
+}
+
+struct Foo;
+
+fn main() {
+    Foo.uwu();
+    //~^ ERROR no method named `uwu` found for struct `Foo` in the current scope
+}
diff --git a/tests/ui/use/unused-trait-with-method-err.stderr b/tests/ui/use/unused-trait-with-method-err.stderr
new file mode 100644
index 00000000000..7ca4563673b
--- /dev/null
+++ b/tests/ui/use/unused-trait-with-method-err.stderr
@@ -0,0 +1,19 @@
+error[E0599]: no method named `uwu` found for struct `Foo` in the current scope
+  --> $DIR/unused-trait-with-method-err.rs:15:9
+   |
+LL | struct Foo;
+   | ---------- method `uwu` not found for this struct
+...
+LL |     Foo.uwu();
+   |         ^^^ method not found in `Foo`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `Bar` defines an item `uwu`, perhaps you need to implement it
+  --> $DIR/unused-trait-with-method-err.rs:7:5
+   |
+LL |     pub trait Bar {
+   |     ^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.