about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs29
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs3
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs13
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs3
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs31
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs7
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs94
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs9
-rw-r--r--compiler/rustc_lint/src/context.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs71
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs7
-rw-r--r--compiler/rustc_type_ir/src/search_graph/global_cache.rs17
-rw-r--r--compiler/rustc_type_ir/src/search_graph/mod.rs168
-rw-r--r--compiler/rustc_type_ir/src/search_graph/stack.rs8
-rw-r--r--library/Cargo.toml10
-rw-r--r--library/core/src/num/int_macros.rs208
-rw-r--r--library/core/src/num/mod.rs4
-rw-r--r--library/core/src/num/saturating.rs46
-rw-r--r--library/core/src/num/uint_macros.rs197
-rw-r--r--src/bootstrap/src/bin/rustc.rs12
-rw-r--r--src/librustdoc/clean/types.rs14
-rw-r--r--src/librustdoc/html/render/write_shared.rs39
-rw-r--r--src/librustdoc/json/conversions.rs344
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs13
-rw-r--r--src/tools/compiletest/src/runtest/run_make.rs4
-rw-r--r--src/tools/run-make-support/src/run.rs25
-rw-r--r--tests/codegen/asm/critical.rs1
-rw-r--r--tests/run-make/c-link-to-rust-va-list-fn/rmake.rs3
-rw-r--r--tests/run-make/fmt-write-bloat/rmake.rs9
-rw-r--r--tests/run-make/textrel-on-minimal-lib/rmake.rs8
-rw-r--r--tests/ui/deprecation/deprecated-expr-precedence.rs8
-rw-r--r--tests/ui/deprecation/deprecated-expr-precedence.stderr11
-rw-r--r--tests/ui/unpretty/deprecated-attr.rs5
-rw-r--r--tests/ui/unpretty/deprecated-attr.stdout9
-rw-r--r--tests/ui/unpretty/diagnostic-attr.stdout4
-rw-r--r--tests/ui/unpretty/exhaustive-asm.hir.stdout2
-rw-r--r--tests/ui/unpretty/exhaustive.hir.stdout69
39 files changed, 574 insertions, 942 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 621e3042b62..44865c493b3 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -206,12 +206,24 @@ impl AttributeExt for Attribute {
         }
     }
 
-    fn style(&self) -> AttrStyle {
-        self.style
+    fn doc_resolution_scope(&self) -> Option<AttrStyle> {
+        match &self.kind {
+            AttrKind::DocComment(..) => Some(self.style),
+            AttrKind::Normal(normal)
+                if normal.item.path == sym::doc && normal.item.value_str().is_some() =>
+            {
+                Some(self.style)
+            }
+            _ => None,
+        }
     }
 }
 
 impl Attribute {
+    pub fn style(&self) -> AttrStyle {
+        self.style
+    }
+
     pub fn may_have_doc_links(&self) -> bool {
         self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str()))
     }
@@ -806,7 +818,14 @@ pub trait AttributeExt: Debug {
     /// * `#[doc(...)]` returns `None`.
     fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)>;
 
-    fn style(&self) -> AttrStyle;
+    /// Returns outer or inner if this is a doc attribute or a sugared doc
+    /// comment, otherwise None.
+    ///
+    /// This is used in the case of doc comments on modules, to decide whether
+    /// to resolve intra-doc links against the symbols in scope within the
+    /// commented module (for inner doc) vs within its parent module (for outer
+    /// doc).
+    fn doc_resolution_scope(&self) -> Option<AttrStyle>;
 }
 
 // FIXME(fn_delegation): use function delegation instead of manually forwarding
@@ -881,8 +900,4 @@ impl Attribute {
     pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
         AttributeExt::doc_str_and_comment_kind(self)
     }
-
-    pub fn style(&self) -> AttrStyle {
-        AttributeExt::style(self)
-    }
 }
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index 066e3e9eceb..f0f5cc4db07 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -240,6 +240,9 @@ pub enum AttributeKind {
     /// Represents `#[optimize(size|speed)]`
     Optimize(OptimizeAttr, Span),
 
+    /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint).
+    PubTransparent(Span),
+
     /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
     Repr(ThinVec<(ReprAttr, Span)>),
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
index d4c846de56e..4cfd9a82ce8 100644
--- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
@@ -19,3 +19,16 @@ impl<S: Stage> SingleAttributeParser<S> for AsPtrParser {
         Some(AttributeKind::AsPtr(cx.attr_span))
     }
 }
+
+pub(crate) struct PubTransparentParser;
+impl<S: Stage> SingleAttributeParser<S> for PubTransparentParser {
+    const PATH: &[Symbol] = &[sym::rustc_pub_transparent];
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
+    const TEMPLATE: AttributeTemplate = template!(Word);
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
+        // FIXME: check that there's no args (this is currently checked elsewhere)
+        Some(AttributeKind::PubTransparent(cx.attr_span))
+    }
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 1bcf500459d..b95ea598e72 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -19,7 +19,7 @@ use crate::attributes::codegen_attrs::{ColdParser, OptimizeParser};
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
 use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
-use crate::attributes::lint_helpers::AsPtrParser;
+use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
 use crate::attributes::repr::{AlignParser, ReprParser};
 use crate::attributes::semantics::MayDangleParser;
 use crate::attributes::stability::{
@@ -113,6 +113,7 @@ attribute_parsers!(
         Single<InlineParser>,
         Single<MayDangleParser>,
         Single<OptimizeParser>,
+        Single<PubTransparentParser>,
         Single<RustcForceInlineParser>,
         Single<TransparencyParser>,
         // tidy-alphabetical-end
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 5b1f1684d54..280b33f0723 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -710,7 +710,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     rustc_attr!(
         rustc_pub_transparent, Normal, template!(Word),
-        WarnFollowing, EncodeCrossCrate::Yes,
+        ErrorFollowing, EncodeCrossCrate::Yes,
         "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
     ),
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1a526d5bce0..679904c7cfe 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1346,12 +1346,13 @@ impl AttributeExt for Attribute {
         }
     }
 
-    #[inline]
-    fn style(&self) -> AttrStyle {
-        match &self {
-            Attribute::Unparsed(u) => u.style,
-            Attribute::Parsed(AttributeKind::DocComment { style, .. }) => *style,
-            _ => panic!(),
+    fn doc_resolution_scope(&self) -> Option<AttrStyle> {
+        match self {
+            Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
+            Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
+                Some(attr.style)
+            }
+            _ => None,
         }
     }
 }
@@ -1442,11 +1443,6 @@ impl Attribute {
     pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
         AttributeExt::doc_str_and_comment_kind(self)
     }
-
-    #[inline]
-    pub fn style(&self) -> AttrStyle {
-        AttributeExt::style(self)
-    }
 }
 
 /// Attributes owned by a HIR owner.
@@ -2286,16 +2282,9 @@ pub struct Expr<'hir> {
 }
 
 impl Expr<'_> {
-    pub fn precedence(
-        &self,
-        for_each_attr: &dyn Fn(HirId, &mut dyn FnMut(&Attribute)),
-    ) -> ExprPrecedence {
+    pub fn precedence(&self, has_attr: &dyn Fn(HirId) -> bool) -> ExprPrecedence {
         let prefix_attrs_precedence = || -> ExprPrecedence {
-            let mut has_outer_attr = false;
-            for_each_attr(self.hir_id, &mut |attr: &Attribute| {
-                has_outer_attr |= matches!(attr.style(), AttrStyle::Outer)
-            });
-            if has_outer_attr { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous }
+            if has_attr(self.hir_id) { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous }
         };
 
         match &self.kind {
@@ -2351,7 +2340,7 @@ impl Expr<'_> {
             | ExprKind::Use(..)
             | ExprKind::Err(_) => prefix_attrs_precedence(),
 
-            ExprKind::DropTemps(expr, ..) => expr.precedence(for_each_attr),
+            ExprKind::DropTemps(expr, ..) => expr.precedence(has_attr),
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 32fec0604c0..752cc2eff97 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -2,6 +2,7 @@ use std::cell::LazyCell;
 use std::ops::ControlFlow;
 
 use rustc_abi::FieldIdx;
+use rustc_attr_data_structures::AttributeKind;
 use rustc_attr_data_structures::ReprAttr::ReprPacked;
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::codes::*;
@@ -1384,7 +1385,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
                 ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
                 ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
                 ty::Adt(def, args) => {
-                    if !def.did().is_local() && !tcx.has_attr(def.did(), sym::rustc_pub_transparent)
+                    if !def.did().is_local()
+                        && !attrs::find_attr!(
+                            tcx.get_all_attrs(def.did()),
+                            AttributeKind::PubTransparent(_)
+                        )
                     {
                         let non_exhaustive = def.is_variant_list_non_exhaustive()
                             || def
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 233bb5cd5b8..d3289e4cc6d 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -10,7 +10,7 @@ use std::vec;
 
 use rustc_abi::ExternAbi;
 use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
-use rustc_ast::{AttrStyle, DUMMY_NODE_ID, DelimArgs};
+use rustc_ast::{DUMMY_NODE_ID, DelimArgs};
 use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
 use rustc_ast_pretty::pp::{self, BoxMarker, Breaks};
 use rustc_ast_pretty::pprust::state::MacHeader;
@@ -81,32 +81,24 @@ impl<'a> State<'a> {
     }
 
     fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence {
-        let for_each_attr = |id: HirId, callback: &mut dyn FnMut(&hir::Attribute)| {
-            self.attrs(id).iter().for_each(callback);
-        };
-        expr.precedence(&for_each_attr)
-    }
-
-    fn print_attrs_as_inner(&mut self, attrs: &[hir::Attribute]) {
-        self.print_either_attributes(attrs, ast::AttrStyle::Inner)
-    }
-
-    fn print_attrs_as_outer(&mut self, attrs: &[hir::Attribute]) {
-        self.print_either_attributes(attrs, ast::AttrStyle::Outer)
+        let has_attr = |id: HirId| !self.attrs(id).is_empty();
+        expr.precedence(&has_attr)
     }
 
-    fn print_either_attributes(&mut self, attrs: &[hir::Attribute], style: ast::AttrStyle) {
+    fn print_attrs(&mut self, attrs: &[hir::Attribute]) {
         if attrs.is_empty() {
             return;
         }
 
         for attr in attrs {
-            self.print_attribute_inline(attr, style);
+            self.print_attribute_as_style(attr, ast::AttrStyle::Outer);
         }
         self.hardbreak_if_not_bol();
     }
 
-    fn print_attribute_inline(&mut self, attr: &hir::Attribute, style: AttrStyle) {
+    /// Print a single attribute as if it has style `style`, disregarding the
+    /// actual style of the attribute.
+    fn print_attribute_as_style(&mut self, attr: &hir::Attribute, style: ast::AttrStyle) {
         match &attr {
             hir::Attribute::Unparsed(unparsed) => {
                 self.maybe_print_comment(unparsed.span.lo());
@@ -118,14 +110,17 @@ impl<'a> State<'a> {
                 self.word("]");
                 self.hardbreak()
             }
-            hir::Attribute::Parsed(AttributeKind::DocComment { style, kind, comment, .. }) => {
+            hir::Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
                 self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string(
-                    *kind, *style, *comment,
+                    *kind, style, *comment,
                 ));
                 self.hardbreak()
             }
             hir::Attribute::Parsed(pa) => {
-                self.word("#[attr = ");
+                match style {
+                    ast::AttrStyle::Inner => self.word("#![attr = "),
+                    ast::AttrStyle::Outer => self.word("#[attr = "),
+                }
                 pa.print_attribute(self);
                 self.word("]");
                 self.hardbreak()
@@ -281,10 +276,17 @@ pub fn print_crate<'a>(
         ann,
     };
 
+    // Print all attributes, regardless of actual style, as inner attributes
+    // since this is the crate root with nothing above it to print outer
+    // attributes.
+    for attr in s.attrs(hir::CRATE_HIR_ID) {
+        s.print_attribute_as_style(attr, ast::AttrStyle::Inner);
+    }
+
     // When printing the AST, we sometimes need to inject `#[no_std]` here.
     // Since you can't compile the HIR, it's not necessary.
 
-    s.print_mod(krate, (*attrs)(hir::CRATE_HIR_ID));
+    s.print_mod(krate);
     s.print_remaining_comments();
     s.s.eof()
 }
@@ -299,7 +301,7 @@ where
 }
 
 pub fn attribute_to_string(ann: &dyn PpAnn, attr: &hir::Attribute) -> String {
-    to_string(ann, |s| s.print_attribute_inline(attr, AttrStyle::Outer))
+    to_string(ann, |s| s.print_attribute_as_style(attr, ast::AttrStyle::Outer))
 }
 
 pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String {
@@ -361,8 +363,7 @@ impl<'a> State<'a> {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span);
     }
 
-    fn print_mod(&mut self, _mod: &hir::Mod<'_>, attrs: &[hir::Attribute]) {
-        self.print_attrs_as_inner(attrs);
+    fn print_mod(&mut self, _mod: &hir::Mod<'_>) {
         for &item_id in _mod.item_ids {
             self.ann.nested(self, Nested::Item(item_id));
         }
@@ -479,7 +480,7 @@ impl<'a> State<'a> {
     fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(item.span.lo());
-        self.print_attrs_as_outer(self.attrs(item.hir_id()));
+        self.print_attrs(self.attrs(item.hir_id()));
         match item.kind {
             hir::ForeignItemKind::Fn(sig, arg_idents, generics) => {
                 let (cb, ib) = self.head("");
@@ -565,7 +566,7 @@ impl<'a> State<'a> {
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(item.span.lo());
         let attrs = self.attrs(item.hir_id());
-        self.print_attrs_as_outer(attrs);
+        self.print_attrs(attrs);
         self.ann.pre(self, AnnNode::Item(item));
         match item.kind {
             hir::ItemKind::ExternCrate(orig_name, ident) => {
@@ -647,14 +648,13 @@ impl<'a> State<'a> {
                 self.print_ident(ident);
                 self.nbsp();
                 self.bopen(ib);
-                self.print_mod(mod_, attrs);
+                self.print_mod(mod_);
                 self.bclose(item.span, cb);
             }
             hir::ItemKind::ForeignMod { abi, items } => {
                 let (cb, ib) = self.head("extern");
                 self.word_nbsp(abi.to_string());
                 self.bopen(ib);
-                self.print_attrs_as_inner(self.attrs(item.hir_id()));
                 for item in items {
                     self.ann.nested(self, Nested::ForeignItem(item.id));
                 }
@@ -731,7 +731,6 @@ impl<'a> State<'a> {
 
                 self.space();
                 self.bopen(ib);
-                self.print_attrs_as_inner(attrs);
                 for impl_item in items {
                     self.ann.nested(self, Nested::ImplItem(impl_item.id));
                 }
@@ -822,7 +821,7 @@ impl<'a> State<'a> {
         for v in variants {
             self.space_if_not_bol();
             self.maybe_print_comment(v.span.lo());
-            self.print_attrs_as_outer(self.attrs(v.hir_id));
+            self.print_attrs(self.attrs(v.hir_id));
             let ib = self.ibox(INDENT_UNIT);
             self.print_variant(v);
             self.word(",");
@@ -857,7 +856,7 @@ impl<'a> State<'a> {
                     self.popen();
                     self.commasep(Inconsistent, struct_def.fields(), |s, field| {
                         s.maybe_print_comment(field.span.lo());
-                        s.print_attrs_as_outer(s.attrs(field.hir_id));
+                        s.print_attrs(s.attrs(field.hir_id));
                         s.print_type(field.ty);
                     });
                     self.pclose();
@@ -878,7 +877,7 @@ impl<'a> State<'a> {
                 for field in struct_def.fields() {
                     self.hardbreak_if_not_bol();
                     self.maybe_print_comment(field.span.lo());
-                    self.print_attrs_as_outer(self.attrs(field.hir_id));
+                    self.print_attrs(self.attrs(field.hir_id));
                     self.print_ident(field.ident);
                     self.word_nbsp(":");
                     self.print_type(field.ty);
@@ -916,7 +915,7 @@ impl<'a> State<'a> {
         self.ann.pre(self, AnnNode::SubItem(ti.hir_id()));
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(ti.span.lo());
-        self.print_attrs_as_outer(self.attrs(ti.hir_id()));
+        self.print_attrs(self.attrs(ti.hir_id()));
         match ti.kind {
             hir::TraitItemKind::Const(ty, default) => {
                 self.print_associated_const(ti.ident, ti.generics, ty, default);
@@ -944,7 +943,7 @@ impl<'a> State<'a> {
         self.ann.pre(self, AnnNode::SubItem(ii.hir_id()));
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(ii.span.lo());
-        self.print_attrs_as_outer(self.attrs(ii.hir_id()));
+        self.print_attrs(self.attrs(ii.hir_id()));
 
         match ii.kind {
             hir::ImplItemKind::Const(ty, expr) => {
@@ -1028,27 +1027,16 @@ impl<'a> State<'a> {
     }
 
     fn print_block(&mut self, blk: &hir::Block<'_>, cb: BoxMarker, ib: BoxMarker) {
-        self.print_block_with_attrs(blk, &[], cb, ib)
+        self.print_block_maybe_unclosed(blk, Some(cb), ib)
     }
 
     fn print_block_unclosed(&mut self, blk: &hir::Block<'_>, ib: BoxMarker) {
-        self.print_block_maybe_unclosed(blk, &[], None, ib)
-    }
-
-    fn print_block_with_attrs(
-        &mut self,
-        blk: &hir::Block<'_>,
-        attrs: &[hir::Attribute],
-        cb: BoxMarker,
-        ib: BoxMarker,
-    ) {
-        self.print_block_maybe_unclosed(blk, attrs, Some(cb), ib)
+        self.print_block_maybe_unclosed(blk, None, ib)
     }
 
     fn print_block_maybe_unclosed(
         &mut self,
         blk: &hir::Block<'_>,
-        attrs: &[hir::Attribute],
         cb: Option<BoxMarker>,
         ib: BoxMarker,
     ) {
@@ -1060,8 +1048,6 @@ impl<'a> State<'a> {
         self.ann.pre(self, AnnNode::Block(blk));
         self.bopen(ib);
 
-        self.print_attrs_as_inner(attrs);
-
         for st in blk.stmts {
             self.print_stmt(st);
         }
@@ -1251,7 +1237,7 @@ impl<'a> State<'a> {
 
     fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
         let cb = self.cbox(INDENT_UNIT);
-        self.print_attrs_as_outer(self.attrs(field.hir_id));
+        self.print_attrs(self.attrs(field.hir_id));
         if !field.is_shorthand {
             self.print_ident(field.ident);
             self.word_space(":");
@@ -1451,7 +1437,7 @@ impl<'a> State<'a> {
 
     fn print_expr(&mut self, expr: &hir::Expr<'_>) {
         self.maybe_print_comment(expr.span.lo());
-        self.print_attrs_as_outer(self.attrs(expr.hir_id));
+        self.print_attrs(self.attrs(expr.hir_id));
         let ib = self.ibox(INDENT_UNIT);
         self.ann.pre(self, AnnNode::Expr(expr));
         match expr.kind {
@@ -2076,7 +2062,7 @@ impl<'a> State<'a> {
             self.space();
         }
         let cb = self.cbox(INDENT_UNIT);
-        self.print_attrs_as_outer(self.attrs(field.hir_id));
+        self.print_attrs(self.attrs(field.hir_id));
         if !field.is_shorthand {
             self.print_ident(field.ident);
             self.word_nbsp(":");
@@ -2086,7 +2072,7 @@ impl<'a> State<'a> {
     }
 
     fn print_param(&mut self, arg: &hir::Param<'_>) {
-        self.print_attrs_as_outer(self.attrs(arg.hir_id));
+        self.print_attrs(self.attrs(arg.hir_id));
         self.print_pat(arg.pat);
     }
 
@@ -2121,7 +2107,7 @@ impl<'a> State<'a> {
         let cb = self.cbox(INDENT_UNIT);
         self.ann.pre(self, AnnNode::Arm(arm));
         let ib = self.ibox(0);
-        self.print_attrs_as_outer(self.attrs(arm.hir_id));
+        self.print_attrs(self.attrs(arm.hir_id));
         self.print_pat(arm.pat);
         self.space();
         if let Some(ref g) = arm.guard {
@@ -2409,7 +2395,7 @@ impl<'a> State<'a> {
     }
 
     fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
-        self.print_attrs_as_outer(self.attrs(predicate.hir_id));
+        self.print_attrs(self.attrs(predicate.hir_id));
         match *predicate.kind {
             hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                 bound_generic_params,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 223cadc056f..bd3ca8317eb 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -18,7 +18,7 @@ use rustc_errors::{
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{Attribute, ExprKind, HirId, QPath};
+use rustc_hir::{ExprKind, HirId, QPath};
 use rustc_hir_analysis::NoVariantNamed;
 use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _};
 use rustc_infer::infer;
@@ -55,7 +55,7 @@ use crate::{
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence {
-        let for_each_attr = |id: HirId, callback: &mut dyn FnMut(&Attribute)| {
+        let has_attr = |id: HirId| -> bool {
             for attr in self.tcx.hir_attrs(id) {
                 // For the purpose of rendering suggestions, disregard attributes
                 // that originate from desugaring of any kind. For example, `x?`
@@ -71,11 +71,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 //     let y: u32 = (x?).try_into().unwrap();
                 //                  +  +++++++++++++++++++++
                 if attr.span().desugaring_kind().is_none() {
-                    callback(attr);
+                    return true;
                 }
             }
+            false
         };
-        expr.precedence(&for_each_attr)
+        expr.precedence(&has_attr)
     }
 
     /// Check an expr with an expectation type, and also demand that the expr's
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b6bf45dfbcf..414f2a1846b 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -855,14 +855,15 @@ impl<'tcx> LateContext<'tcx> {
     /// rendering diagnostic. This is not the same as the precedence that would
     /// be used for pretty-printing HIR by rustc_hir_pretty.
     pub fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence {
-        let for_each_attr = |id: hir::HirId, callback: &mut dyn FnMut(&hir::Attribute)| {
+        let has_attr = |id: hir::HirId| -> bool {
             for attr in self.tcx.hir_attrs(id) {
                 if attr.span().desugaring_kind().is_none() {
-                    callback(attr);
+                    return true;
                 }
             }
+            false
         };
-        expr.precedence(&for_each_attr)
+        expr.precedence(&has_attr)
     }
 
     /// If the given expression is a local binding, find the initializer expression.
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 7ead0a6d6b7..00fd3ba8046 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -430,7 +430,7 @@ where
                 canonical_input,
                 step_kind_from_parent,
                 &mut canonical_goal_evaluation,
-                |search_graph, canonical_goal_evaluation| {
+                |search_graph, cx, canonical_input, canonical_goal_evaluation| {
                     EvalCtxt::enter_canonical(
                         cx,
                         search_graph,
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index d0630383477..d802bf4df19 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -116,6 +116,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         let mut seen = FxHashMap::default();
         let attrs = self.tcx.hir_attrs(hir_id);
         for attr in attrs {
+            let mut style = None;
             match attr {
                 Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
                     self.check_confusables(*first_span, target);
@@ -149,6 +150,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 }
                 Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */
                 }
+
+                &Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => {
+                    self.check_rustc_pub_transparent(attr_span, span, attrs)
+                }
                 Attribute::Parsed(AttributeKind::Cold(attr_span)) => {
                     self.check_cold(hir_id, *attr_span, span, target)
                 }
@@ -163,10 +168,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
                     self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
                 }
-                &Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
-                    self.check_may_dangle(hir_id, attr_span)
+                Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
+                    self.check_may_dangle(hir_id, *attr_span)
                 }
-                Attribute::Unparsed(_) => {
+                Attribute::Unparsed(attr_item) => {
+                    style = Some(attr_item.style);
                     match attr.path().as_slice() {
                         [sym::diagnostic, sym::do_not_recommend, ..] => {
                             self.check_do_not_recommend(attr.span(), hir_id, target, attr, item)
@@ -189,6 +195,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         }
                         [sym::doc, ..] => self.check_doc_attrs(
                             attr,
+                            attr_item.style,
                             hir_id,
                             target,
                             &mut specified_inline,
@@ -288,7 +295,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             self.check_type_const(hir_id,attr, target);
                         }
                         [sym::linkage, ..] => self.check_linkage(attr, span, target),
-                        [sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent(attr.span(), span, attrs),
                         [
                             // ok
                             sym::allow
@@ -350,14 +356,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) =
                     attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name))
                 {
-                    match attr.style() {
-                        ast::AttrStyle::Outer => self.tcx.emit_node_span_lint(
+                    match style {
+                        Some(ast::AttrStyle::Outer) => self.tcx.emit_node_span_lint(
                             UNUSED_ATTRIBUTES,
                             hir_id,
                             attr.span(),
                             errors::OuterCrateLevelAttr,
                         ),
-                        ast::AttrStyle::Inner => self.tcx.emit_node_span_lint(
+                        Some(ast::AttrStyle::Inner) | None => self.tcx.emit_node_span_lint(
                             UNUSED_ATTRIBUTES,
                             hir_id,
                             attr.span(),
@@ -371,7 +377,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 check_duplicates(self.tcx, attr, hir_id, *duplicates, &mut seen);
             }
 
-            self.check_unused_attribute(hir_id, attr)
+            self.check_unused_attribute(hir_id, attr, style)
         }
 
         self.check_repr(attrs, span, target, item, hir_id);
@@ -1194,7 +1200,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     /// the first `inline`/`no_inline` attribute.
     fn check_doc_inline(
         &self,
-        attr: &Attribute,
+        style: AttrStyle,
         meta: &MetaItemInner,
         hir_id: HirId,
         target: Target,
@@ -1224,8 +1230,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     meta.span(),
                     errors::DocInlineOnlyUse {
                         attr_span: meta.span(),
-                        item_span: (attr.style() == AttrStyle::Outer)
-                            .then(|| self.tcx.hir_span(hir_id)),
+                        item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)),
                     },
                 );
             }
@@ -1234,7 +1239,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
     fn check_doc_masked(
         &self,
-        attr: &Attribute,
+        style: AttrStyle,
         meta: &MetaItemInner,
         hir_id: HirId,
         target: Target,
@@ -1246,8 +1251,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 meta.span(),
                 errors::DocMaskedOnlyExternCrate {
                     attr_span: meta.span(),
-                    item_span: (attr.style() == AttrStyle::Outer)
-                        .then(|| self.tcx.hir_span(hir_id)),
+                    item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)),
                 },
             );
             return;
@@ -1260,8 +1264,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 meta.span(),
                 errors::DocMaskedNotExternCrateSelf {
                     attr_span: meta.span(),
-                    item_span: (attr.style() == AttrStyle::Outer)
-                        .then(|| self.tcx.hir_span(hir_id)),
+                    item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)),
                 },
             );
         }
@@ -1285,13 +1288,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     fn check_attr_crate_level(
         &self,
         attr: &Attribute,
+        style: AttrStyle,
         meta: &MetaItemInner,
         hir_id: HirId,
     ) -> bool {
         if hir_id != CRATE_HIR_ID {
             // insert a bang between `#` and `[...`
             let bang_span = attr.span().lo() + BytePos(1);
-            let sugg = (attr.style() == AttrStyle::Outer
+            let sugg = (style == AttrStyle::Outer
                 && self.tcx.hir_get_parent_item(hir_id) == CRATE_OWNER_ID)
                 .then_some(errors::AttrCrateLevelOnlySugg {
                     attr: attr.span().with_lo(bang_span).with_hi(bang_span),
@@ -1308,7 +1312,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     /// Checks that `doc(test(...))` attribute contains only valid attributes and are at the right place.
-    fn check_test_attr(&self, attr: &Attribute, meta: &MetaItemInner, hir_id: HirId) {
+    fn check_test_attr(
+        &self,
+        attr: &Attribute,
+        style: AttrStyle,
+        meta: &MetaItemInner,
+        hir_id: HirId,
+    ) {
         if let Some(metas) = meta.meta_item_list() {
             for i_meta in metas {
                 match (i_meta.name(), i_meta.meta_item()) {
@@ -1316,7 +1326,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         // Allowed everywhere like `#[doc]`
                     }
                     (Some(sym::no_crate_inject), _) => {
-                        self.check_attr_crate_level(attr, meta, hir_id);
+                        self.check_attr_crate_level(attr, style, meta, hir_id);
                     }
                     (_, Some(m)) => {
                         self.tcx.emit_node_span_lint(
@@ -1370,6 +1380,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     fn check_doc_attrs(
         &self,
         attr: &Attribute,
+        style: AttrStyle,
         hir_id: HirId,
         target: Target,
         specified_inline: &mut Option<(bool, Span)>,
@@ -1404,7 +1415,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         }
 
                         Some(sym::test) => {
-                            self.check_test_attr(attr, meta, hir_id);
+                            self.check_test_attr(attr, style, meta, hir_id);
                         }
 
                         Some(
@@ -1415,25 +1426,25 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::html_root_url
                             | sym::html_no_source,
                         ) => {
-                            self.check_attr_crate_level(attr, meta, hir_id);
+                            self.check_attr_crate_level(attr, style, meta, hir_id);
                         }
 
                         Some(sym::cfg_hide) => {
-                            if self.check_attr_crate_level(attr, meta, hir_id) {
+                            if self.check_attr_crate_level(attr, style, meta, hir_id) {
                                 self.check_doc_cfg_hide(meta, hir_id);
                             }
                         }
 
                         Some(sym::inline | sym::no_inline) => {
-                            self.check_doc_inline(attr, meta, hir_id, target, specified_inline)
+                            self.check_doc_inline(style, meta, hir_id, target, specified_inline)
                         }
 
-                        Some(sym::masked) => self.check_doc_masked(attr, meta, hir_id, target),
+                        Some(sym::masked) => self.check_doc_masked(style, meta, hir_id, target),
 
                         Some(sym::cfg | sym::hidden | sym::notable_trait) => {}
 
                         Some(sym::rust_logo) => {
-                            if self.check_attr_crate_level(attr, meta, hir_id)
+                            if self.check_attr_crate_level(attr, style, meta, hir_id)
                                 && !self.tcx.features().rustdoc_internals()
                             {
                                 feature_err(
@@ -1472,7 +1483,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                     errors::DocTestUnknownInclude {
                                         path,
                                         value: value.to_string(),
-                                        inner: match attr.style() {
+                                        inner: match style {
                                             AttrStyle::Inner => "!",
                                             AttrStyle::Outer => "",
                                         },
@@ -2426,7 +2437,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute) {
+    fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute, style: Option<AttrStyle>) {
         // FIXME(jdonszelmann): deduplicate these checks after more attrs are parsed. This is very
         // ugly now but can 100% be removed later.
         if let Attribute::Parsed(p) = attr {
@@ -2479,14 +2490,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             })
         {
             if hir_id != CRATE_HIR_ID {
-                match attr.style() {
-                    ast::AttrStyle::Outer => self.tcx.emit_node_span_lint(
+                match style {
+                    Some(ast::AttrStyle::Outer) => self.tcx.emit_node_span_lint(
                         UNUSED_ATTRIBUTES,
                         hir_id,
                         attr.span(),
                         errors::OuterCrateLevelAttr,
                     ),
-                    ast::AttrStyle::Inner => self.tcx.emit_node_span_lint(
+                    Some(ast::AttrStyle::Inner) | None => self.tcx.emit_node_span_lint(
                         UNUSED_ATTRIBUTES,
                         hir_id,
                         attr.span(),
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index fa839d2748d..931c6241bf2 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -356,7 +356,12 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGen
 /// If there are no doc-comments, return true.
 /// FIXME(#78591): Support both inner and outer attributes on the same item.
 pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
-    attrs.iter().find(|a| a.doc_str().is_some()).is_none_or(|a| a.style() == ast::AttrStyle::Inner)
+    for attr in attrs {
+        if let Some(attr_style) = attr.doc_resolution_scope() {
+            return attr_style == ast::AttrStyle::Inner;
+        }
+    }
+    true
 }
 
 /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.
diff --git a/compiler/rustc_type_ir/src/search_graph/global_cache.rs b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
index a2442660259..1b99cc820f1 100644
--- a/compiler/rustc_type_ir/src/search_graph/global_cache.rs
+++ b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
@@ -2,6 +2,7 @@ use derive_where::derive_where;
 
 use super::{AvailableDepth, Cx, NestedGoals};
 use crate::data_structures::HashMap;
+use crate::search_graph::EvaluationResult;
 
 struct Success<X: Cx> {
     required_depth: usize,
@@ -43,28 +44,26 @@ impl<X: Cx> GlobalCache<X> {
         &mut self,
         cx: X,
         input: X::Input,
-
-        origin_result: X::Result,
+        evaluation_result: EvaluationResult<X>,
         dep_node: X::DepNodeIndex,
-
-        required_depth: usize,
-        encountered_overflow: bool,
-        nested_goals: NestedGoals<X>,
     ) {
-        let result = cx.mk_tracked(origin_result, dep_node);
+        let EvaluationResult { encountered_overflow, required_depth, heads, nested_goals, result } =
+            evaluation_result;
+        debug_assert!(heads.is_empty());
+        let result = cx.mk_tracked(result, dep_node);
         let entry = self.map.entry(input).or_default();
         if encountered_overflow {
             let with_overflow = WithOverflow { nested_goals, result };
             let prev = entry.with_overflow.insert(required_depth, with_overflow);
             if let Some(prev) = &prev {
                 assert!(cx.evaluation_is_concurrent());
-                assert_eq!(cx.get_tracked(&prev.result), origin_result);
+                assert_eq!(cx.get_tracked(&prev.result), evaluation_result.result);
             }
         } else {
             let prev = entry.success.replace(Success { required_depth, nested_goals, result });
             if let Some(prev) = &prev {
                 assert!(cx.evaluation_is_concurrent());
-                assert_eq!(cx.get_tracked(&prev.result), origin_result);
+                assert_eq!(cx.get_tracked(&prev.result), evaluation_result.result);
             }
         }
     }
diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs
index b59b4f92854..a857da2fcd5 100644
--- a/compiler/rustc_type_ir/src/search_graph/mod.rs
+++ b/compiler/rustc_type_ir/src/search_graph/mod.rs
@@ -1,16 +1,16 @@
-/// The search graph is responsible for caching and cycle detection in the trait
-/// solver. Making sure that caching doesn't result in soundness bugs or unstable
-/// query results is very challenging and makes this one of the most-involved
-/// self-contained components of the compiler.
-///
-/// We added fuzzing support to test its correctness. The fuzzers used to verify
-/// the current implementation can be found in https://github.com/lcnr/search_graph_fuzz.
-///
-/// This is just a quick overview of the general design, please check out the relevant
-/// [rustc-dev-guide chapter](https://rustc-dev-guide.rust-lang.org/solve/caching.html) for
-/// more details. Caching is split between a global cache and the per-cycle `provisional_cache`.
-/// The global cache has to be completely unobservable, while the per-cycle cache may impact
-/// behavior as long as the resulting behavior is still correct.
+//! The search graph is responsible for caching and cycle detection in the trait
+//! solver. Making sure that caching doesn't result in soundness bugs or unstable
+//! query results is very challenging and makes this one of the most-involved
+//! self-contained components of the compiler.
+//!
+//! We added fuzzing support to test its correctness. The fuzzers used to verify
+//! the current implementation can be found in <https://github.com/lcnr/search_graph_fuzz>.
+//!
+//! This is just a quick overview of the general design, please check out the relevant
+//! [rustc-dev-guide chapter](https://rustc-dev-guide.rust-lang.org/solve/caching.html) for
+//! more details. Caching is split between a global cache and the per-cycle `provisional_cache`.
+//! The global cache has to be completely unobservable, while the per-cycle cache may impact
+//! behavior as long as the resulting behavior is still correct.
 use std::cmp::Ordering;
 use std::collections::BTreeMap;
 use std::collections::hash_map::Entry;
@@ -381,18 +381,16 @@ impl PathsToNested {
 /// The nested goals of each stack entry and the path from the
 /// stack entry to that nested goal.
 ///
+/// They are used when checking whether reevaluating a global cache
+/// would encounter a cycle or use a provisional cache entry given the
+/// currentl search graph state. We need to disable the global cache
+/// in this case as it could otherwise result in behaviorial differences.
+/// Cycles can impact behavior. The cycle ABA may have different final
+/// results from a the cycle BAB depending on the cycle root.
+///
 /// We only start tracking nested goals once we've either encountered
 /// overflow or a solver cycle. This is a performance optimization to
 /// avoid tracking nested goals on the happy path.
-///
-/// We use nested goals for two reasons:
-/// - when rebasing provisional cache entries
-/// - when checking whether we have to ignore a global cache entry as reevaluating
-///   it would encounter a cycle or use a provisional cache entry.
-///
-/// We need to disable the global cache if using it would hide a cycle, as
-/// cycles can impact behavior. The cycle ABA may have different final
-/// results from a the cycle BAB depending on the cycle root.
 #[derive_where(Debug, Default, Clone; X: Cx)]
 struct NestedGoals<X: Cx> {
     nested_goals: HashMap<X::Input, PathsToNested>,
@@ -450,6 +448,43 @@ struct ProvisionalCacheEntry<X: Cx> {
     result: X::Result,
 }
 
+/// The final result of evaluating a goal.
+///
+/// We reset `encountered_overflow` when reevaluating a goal,
+/// but need to track whether we've hit the recursion limit at
+/// all for correctness.
+///
+/// We've previously simply returned the final `StackEntry` but this
+/// made it easy to accidentally drop information from the previous
+/// evaluation.
+#[derive_where(Debug; X: Cx)]
+struct EvaluationResult<X: Cx> {
+    encountered_overflow: bool,
+    required_depth: usize,
+    heads: CycleHeads,
+    nested_goals: NestedGoals<X>,
+    result: X::Result,
+}
+
+impl<X: Cx> EvaluationResult<X> {
+    fn finalize(
+        final_entry: StackEntry<X>,
+        encountered_overflow: bool,
+        result: X::Result,
+    ) -> EvaluationResult<X> {
+        EvaluationResult {
+            encountered_overflow,
+            // Unlike `encountered_overflow`, we share `heads`, `required_depth`,
+            // and `nested_goals` between evaluations.
+            required_depth: final_entry.required_depth,
+            heads: final_entry.heads,
+            nested_goals: final_entry.nested_goals,
+            // We only care about the final result.
+            result,
+        }
+    }
+}
+
 pub struct SearchGraph<D: Delegate<Cx = X>, X: Cx = <D as Delegate>::Cx> {
     root_depth: AvailableDepth,
     /// The stack of goals currently being computed.
@@ -562,7 +597,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
         input: X::Input,
         step_kind_from_parent: PathKind,
         inspect: &mut D::ProofTreeBuilder,
-        mut evaluate_goal: impl FnMut(&mut Self, &mut D::ProofTreeBuilder) -> X::Result,
+        evaluate_goal: impl Fn(&mut Self, X, X::Input, &mut D::ProofTreeBuilder) -> X::Result + Copy,
     ) -> X::Result {
         let Some(available_depth) =
             AvailableDepth::allowed_depth_for_nested::<D>(self.root_depth, &self.stack)
@@ -616,12 +651,12 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
             input,
             step_kind_from_parent,
             available_depth,
+            provisional_result: None,
             required_depth: 0,
             heads: Default::default(),
             encountered_overflow: false,
             has_been_used: None,
             nested_goals: Default::default(),
-            provisional_result: None,
         });
 
         // This is for global caching, so we properly track query dependencies.
@@ -630,35 +665,41 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
         // not tracked by the cache key and from outside of this anon task, it
         // must not be added to the global cache. Notably, this is the case for
         // trait solver cycles participants.
-        let ((final_entry, result), dep_node) = cx.with_cached_task(|| {
-            self.evaluate_goal_in_task(cx, input, inspect, &mut evaluate_goal)
-        });
+        let (evaluation_result, dep_node) =
+            cx.with_cached_task(|| self.evaluate_goal_in_task(cx, input, inspect, evaluate_goal));
 
         // We've finished computing the goal and have popped it from the stack,
         // lazily update its parent goal.
         Self::update_parent_goal(
             &mut self.stack,
-            final_entry.step_kind_from_parent,
-            final_entry.required_depth,
-            &final_entry.heads,
-            final_entry.encountered_overflow,
-            UpdateParentGoalCtxt::Ordinary(&final_entry.nested_goals),
+            step_kind_from_parent,
+            evaluation_result.required_depth,
+            &evaluation_result.heads,
+            evaluation_result.encountered_overflow,
+            UpdateParentGoalCtxt::Ordinary(&evaluation_result.nested_goals),
         );
+        let result = evaluation_result.result;
 
         // We're now done with this goal. We only add the root of cycles to the global cache.
         // In case this goal is involved in a larger cycle add it to the provisional cache.
-        if final_entry.heads.is_empty() {
+        if evaluation_result.heads.is_empty() {
             if let Some((_scope, expected)) = validate_cache {
                 // Do not try to move a goal into the cache again if we're testing
                 // the global cache.
-                assert_eq!(result, expected, "input={input:?}");
+                assert_eq!(evaluation_result.result, expected, "input={input:?}");
             } else if D::inspect_is_noop(inspect) {
-                self.insert_global_cache(cx, final_entry, result, dep_node)
+                self.insert_global_cache(cx, input, evaluation_result, dep_node)
             }
         } else if D::ENABLE_PROVISIONAL_CACHE {
             debug_assert!(validate_cache.is_none(), "unexpected non-root: {input:?}");
             let entry = self.provisional_cache.entry(input).or_default();
-            let StackEntry { heads, encountered_overflow, .. } = final_entry;
+            let EvaluationResult {
+                encountered_overflow,
+                required_depth: _,
+                heads,
+                nested_goals: _,
+                result,
+            } = evaluation_result;
             let path_from_head = Self::cycle_path_kind(
                 &self.stack,
                 step_kind_from_parent,
@@ -1023,19 +1064,25 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
         cx: X,
         input: X::Input,
         inspect: &mut D::ProofTreeBuilder,
-        mut evaluate_goal: impl FnMut(&mut Self, &mut D::ProofTreeBuilder) -> X::Result,
-    ) -> (StackEntry<X>, X::Result) {
+        evaluate_goal: impl Fn(&mut Self, X, X::Input, &mut D::ProofTreeBuilder) -> X::Result + Copy,
+    ) -> EvaluationResult<X> {
+        // We reset `encountered_overflow` each time we rerun this goal
+        // but need to make sure we currently propagate it to the global
+        // cache even if only some of the evaluations actually reach the
+        // recursion limit.
+        let mut encountered_overflow = false;
         let mut i = 0;
         loop {
-            let result = evaluate_goal(self, inspect);
+            let result = evaluate_goal(self, cx, input, inspect);
             let stack_entry = self.stack.pop();
+            encountered_overflow |= stack_entry.encountered_overflow;
             debug_assert_eq!(stack_entry.input, input);
 
             // If the current goal is not the root of a cycle, we are done.
             //
             // There are no provisional cache entries which depend on this goal.
             let Some(usage_kind) = stack_entry.has_been_used else {
-                return (stack_entry, result);
+                return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
             };
 
             // If it is a cycle head, we have to keep trying to prove it until
@@ -1051,7 +1098,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
             // final result is equal to the initial response for that case.
             if self.reached_fixpoint(cx, &stack_entry, usage_kind, result) {
                 self.rebase_provisional_cache_entries(&stack_entry, |_, result| result);
-                return (stack_entry, result);
+                return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
             }
 
             // If computing this goal results in ambiguity with no constraints,
@@ -1070,7 +1117,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
                 self.rebase_provisional_cache_entries(&stack_entry, |input, _| {
                     D::propagate_ambiguity(cx, input, result)
                 });
-                return (stack_entry, result);
+                return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
             };
 
             // If we've reached the fixpoint step limit, we bail with overflow and taint all
@@ -1082,7 +1129,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
                 self.rebase_provisional_cache_entries(&stack_entry, |input, _| {
                     D::on_fixpoint_overflow(cx, input)
                 });
-                return (stack_entry, result);
+                return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
             }
 
             // Clear all provisional cache entries which depend on a previous provisional
@@ -1091,9 +1138,22 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
 
             debug!(?result, "fixpoint changed provisional results");
             self.stack.push(StackEntry {
-                has_been_used: None,
+                input,
+                step_kind_from_parent: stack_entry.step_kind_from_parent,
+                available_depth: stack_entry.available_depth,
                 provisional_result: Some(result),
-                ..stack_entry
+                // We can keep these goals from previous iterations as they are only
+                // ever read after finalizing this evaluation.
+                required_depth: stack_entry.required_depth,
+                heads: stack_entry.heads,
+                nested_goals: stack_entry.nested_goals,
+                // We reset these two fields when rerunning this goal. We could
+                // keep `encountered_overflow` as it's only used as a performance
+                // optimization. However, given that the proof tree will likely look
+                // similar to the previous iterations when reevaluating, it's better
+                // for caching if the reevaluation also starts out with `false`.
+                encountered_overflow: false,
+                has_been_used: None,
             });
         }
     }
@@ -1109,21 +1169,11 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
     fn insert_global_cache(
         &mut self,
         cx: X,
-        final_entry: StackEntry<X>,
-        result: X::Result,
+        input: X::Input,
+        evaluation_result: EvaluationResult<X>,
         dep_node: X::DepNodeIndex,
     ) {
-        debug!(?final_entry, ?result, "insert global cache");
-        cx.with_global_cache(|cache| {
-            cache.insert(
-                cx,
-                final_entry.input,
-                result,
-                dep_node,
-                final_entry.required_depth,
-                final_entry.encountered_overflow,
-                final_entry.nested_goals,
-            )
-        })
+        debug!(?evaluation_result, "insert global cache");
+        cx.with_global_cache(|cache| cache.insert(cx, input, evaluation_result, dep_node))
     }
 }
diff --git a/compiler/rustc_type_ir/src/search_graph/stack.rs b/compiler/rustc_type_ir/src/search_graph/stack.rs
index 8bb247bf055..e0fd934df69 100644
--- a/compiler/rustc_type_ir/src/search_graph/stack.rs
+++ b/compiler/rustc_type_ir/src/search_graph/stack.rs
@@ -26,6 +26,10 @@ pub(super) struct StackEntry<X: Cx> {
     /// The available depth of a given goal, immutable.
     pub available_depth: AvailableDepth,
 
+    /// Starts out as `None` and gets set when rerunning this
+    /// goal in case we encounter a cycle.
+    pub provisional_result: Option<X::Result>,
+
     /// The maximum depth required while evaluating this goal.
     pub required_depth: usize,
 
@@ -42,10 +46,6 @@ pub(super) struct StackEntry<X: Cx> {
 
     /// The nested goals of this goal, see the doc comment of the type.
     pub nested_goals: NestedGoals<X>,
-
-    /// Starts out as `None` and gets set when rerunning this
-    /// goal in case we encounter a cycle.
-    pub provisional_result: Option<X::Result>,
 }
 
 #[derive_where(Default; X: Cx)]
diff --git a/library/Cargo.toml b/library/Cargo.toml
index 35480b9319d..c66f621ffde 100644
--- a/library/Cargo.toml
+++ b/library/Cargo.toml
@@ -1,3 +1,5 @@
+cargo-features = ["profile-rustflags"]
+
 [workspace]
 resolver = "1"
 members = [
@@ -44,6 +46,14 @@ object.debug = 0
 rustc-demangle.debug = 0
 rustc-demangle.opt-level = "s"
 
+# panic_abort must always be compiled with panic=abort, even when the rest of the
+# sysroot is panic=unwind.
+[profile.dev.package.panic_abort]
+rustflags = ["-Cpanic=abort"]
+
+[profile.release.package.panic_abort]
+rustflags = ["-Cpanic=abort"]
+
 [patch.crates-io]
 # See comments in `library/rustc-std-workspace-core/README.md` for what's going on
 # here
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 3a7bc902f93..5683d5ec92d 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -29,8 +29,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");")]
         /// ```
@@ -42,8 +40,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");")]
         /// ```
@@ -64,8 +60,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0b100_0000", stringify!($SelfT), ";")]
         ///
@@ -85,8 +79,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 1);")]
         /// ```
@@ -106,8 +98,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = -1", stringify!($SelfT), ";")]
         ///
@@ -127,8 +117,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = -4", stringify!($SelfT), ";")]
         ///
@@ -147,8 +135,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = -1", stringify!($SelfT), ";")]
         ///
@@ -167,8 +153,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 3", stringify!($SelfT), ";")]
         ///
@@ -188,8 +172,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(isolate_most_least_significant_one)]
         ///
@@ -211,8 +193,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(isolate_most_least_significant_one)]
         ///
@@ -236,8 +216,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = -1", stringify!($SelfT), ";")]
         ///
@@ -259,8 +237,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $rot_op, stringify!($SelfT), ";")]
         #[doc = concat!("let m = ", $rot_result, ";")]
@@ -284,8 +260,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $rot_result, stringify!($SelfT), ";")]
         #[doc = concat!("let m = ", $rot_op, ";")]
@@ -305,8 +279,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $swap_op, stringify!($SelfT), ";")]
         ///
@@ -328,8 +300,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $swap_op, stringify!($SelfT), ";")]
         /// let m = n.reverse_bits();
@@ -352,8 +322,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -384,8 +352,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -416,8 +382,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -449,8 +413,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -481,8 +443,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(1), Some(", stringify!($SelfT), "::MAX - 1));")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);")]
@@ -508,8 +468,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).strict_add(1), ", stringify!($SelfT), "::MAX - 1);")]
@@ -576,8 +534,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_unsigned(2), Some(3));")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add_unsigned(3), None);")]
@@ -603,8 +559,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_add_unsigned(2), 3);")]
@@ -631,8 +585,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).checked_sub(1), Some(", stringify!($SelfT), "::MIN + 1));")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).checked_sub(3), None);")]
@@ -658,8 +610,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).strict_sub(1), ", stringify!($SelfT), "::MIN + 1);")]
@@ -726,8 +676,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_unsigned(2), Some(-1));")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).checked_sub_unsigned(3), None);")]
@@ -753,8 +701,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_sub_unsigned(2), -1);")]
@@ -781,8 +727,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(1), Some(", stringify!($SelfT), "::MAX));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);")]
@@ -808,8 +752,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.strict_mul(1), ", stringify!($SelfT), "::MAX);")]
@@ -876,8 +818,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).checked_div(-1), Some(", stringify!($Max), "));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_div(-1), None);")]
@@ -914,8 +854,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).strict_div(-1), ", stringify!($Max), ");")]
@@ -949,8 +887,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).checked_div_euclid(-1), Some(", stringify!($Max), "));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_div_euclid(-1), None);")]
@@ -987,8 +923,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).strict_div_euclid(-1), ", stringify!($Max), ");")]
@@ -1023,8 +957,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(exact_div)]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).checked_exact_div(-1), Some(", stringify!($Max), "));")]
@@ -1063,8 +995,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(exact_div)]
         #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), 32);")]
@@ -1126,8 +1056,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));")]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);")]
@@ -1163,8 +1091,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_rem(2), 1);")]
@@ -1198,8 +1124,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));")]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);")]
@@ -1235,8 +1159,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_rem_euclid(2), 1);")]
@@ -1269,8 +1191,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_neg(), Some(-5));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);")]
@@ -1328,8 +1248,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_neg(), -5);")]
@@ -1356,8 +1274,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));")]
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);")]
@@ -1389,8 +1305,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".strict_shl(4), 0x10);")]
@@ -1453,7 +1367,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
@@ -1478,8 +1391,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));")]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);")]
@@ -1510,8 +1421,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".strict_shr(4), 0x1);")]
@@ -1575,7 +1484,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
@@ -1605,8 +1513,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((-5", stringify!($SelfT), ").checked_abs(), Some(5));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);")]
@@ -1635,8 +1541,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!((-5", stringify!($SelfT), ").strict_abs(), 5);")]
@@ -1666,8 +1570,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);")]
@@ -1709,8 +1611,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(8", stringify!($SelfT), ".strict_pow(2), 64);")]
@@ -1753,7 +1653,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")]
         /// ```
@@ -1801,8 +1700,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(100), ", stringify!($SelfT), "::MAX);")]
@@ -1823,8 +1720,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_unsigned(2), 3);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_add_unsigned(100), ", stringify!($SelfT), "::MAX);")]
@@ -1848,8 +1743,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.saturating_sub(100), ", stringify!($SelfT), "::MIN);")]
@@ -1869,8 +1762,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_sub_unsigned(127), -27);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.saturating_sub_unsigned(100), ", stringify!($SelfT), "::MIN);")]
@@ -1894,8 +1785,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_neg(), -100);")]
         #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").saturating_neg(), 100);")]
@@ -1917,8 +1806,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_abs(), 100);")]
         #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").saturating_abs(), 100);")]
@@ -1944,8 +1831,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".saturating_mul(12), 120);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_mul(10), ", stringify!($SelfT), "::MAX);")]
@@ -1976,8 +1861,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".saturating_div(2), 2);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_div(-1), ", stringify!($SelfT), "::MIN + 1);")]
@@ -2001,8 +1884,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT), "::MAX);")]
@@ -2026,8 +1907,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_add(27), 127);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_add(2), ", stringify!($SelfT), "::MIN + 1);")]
@@ -2046,8 +1925,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_add_unsigned(27), 127);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_add_unsigned(2), ", stringify!($SelfT), "::MIN + 1);")]
@@ -2066,8 +1943,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".wrapping_sub(127), -127);")]
         #[doc = concat!("assert_eq!((-2", stringify!($SelfT), ").wrapping_sub(", stringify!($SelfT), "::MAX), ", stringify!($SelfT), "::MAX);")]
@@ -2086,8 +1961,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".wrapping_sub_unsigned(127), -127);")]
         #[doc = concat!("assert_eq!((-2", stringify!($SelfT), ").wrapping_sub_unsigned(", stringify!($UnsignedT), "::MAX), -1);")]
@@ -2106,8 +1979,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".wrapping_mul(12), 120);")]
         /// assert_eq!(11i8.wrapping_mul(12), -124);
@@ -2134,8 +2005,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);")]
         /// assert_eq!((-128i8).wrapping_div(-1), -128);
@@ -2162,8 +2031,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);")]
         /// assert_eq!((-128i8).wrapping_div_euclid(-1), -128);
@@ -2190,8 +2057,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);")]
         /// assert_eq!((-128i8).wrapping_rem(-1), 0);
@@ -2217,8 +2082,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);")]
         /// assert_eq!((-128i8).wrapping_rem_euclid(-1), 0);
@@ -2241,8 +2104,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);")]
         #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").wrapping_neg(), 100);")]
@@ -2267,8 +2128,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);")]
         #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);")]
@@ -2296,8 +2155,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);")]
         /// assert_eq!((-128i16).wrapping_shr(64), -128);
@@ -2324,8 +2181,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_abs(), 100);")]
         #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").wrapping_abs(), 100);")]
@@ -2352,8 +2207,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".unsigned_abs(), 100", stringify!($UnsignedT), ");")]
         #[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").unsigned_abs(), 100", stringify!($UnsignedT), ");")]
@@ -2373,8 +2226,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81);")]
         /// assert_eq!(3i8.wrapping_pow(5), -13);
@@ -2432,8 +2283,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($SelfT), "::MIN, true));")]
@@ -2513,8 +2362,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_unsigned(2), (3, false));")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN).overflowing_add_unsigned(", stringify!($UnsignedT), "::MAX), (", stringify!($SelfT), "::MAX, false));")]
@@ -2538,8 +2385,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));")]
@@ -2620,8 +2465,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_unsigned(2), (-1, false));")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX).overflowing_sub_unsigned(", stringify!($UnsignedT), "::MAX), (", stringify!($SelfT), "::MIN, false));")]
@@ -2645,8 +2488,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_mul(2), (10, false));")]
         /// assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));
@@ -2671,8 +2512,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `i32` is used here.
         ///
@@ -2704,8 +2543,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `i32` is used here.
         ///
@@ -2744,8 +2581,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `i32` is used here.
         ///
@@ -2780,8 +2615,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div(-1), (", stringify!($SelfT), "::MIN, true));")]
@@ -2811,8 +2644,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringify!($SelfT), "::MIN, true));")]
@@ -2842,8 +2673,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem(-1), (0, true));")]
@@ -2873,8 +2702,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true));")]
@@ -2902,8 +2729,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($SelfT), "::MIN, true));")]
@@ -2930,8 +2755,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT),".overflowing_shl(4), (0x10, false));")]
         /// assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));
@@ -2954,8 +2777,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));")]
         /// assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));
@@ -2979,8 +2800,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".overflowing_abs(), (10, false));")]
         #[doc = concat!("assert_eq!((-10", stringify!($SelfT), ").overflowing_abs(), (10, false));")]
@@ -3002,8 +2821,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false));")]
         /// assert_eq!(3i8.overflowing_pow(5), (-13, true));
@@ -3045,8 +2862,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let x: ", stringify!($SelfT), " = 2; // or any other integer type")]
         ///
@@ -3106,7 +2921,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")]
         /// ```
@@ -3142,8 +2956,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let a: ", stringify!($SelfT), " = 7; // or any other integer type")]
         /// let b = 4;
@@ -3181,8 +2993,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let a: ", stringify!($SelfT), " = 7; // or any other integer type")]
         /// let b = 4;
@@ -3230,8 +3040,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(int_roundings)]
         #[doc = concat!("let a: ", stringify!($SelfT)," = 8;")]
@@ -3274,8 +3082,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(int_roundings)]
         #[doc = concat!("let a: ", stringify!($SelfT)," = 8;")]
@@ -3321,8 +3127,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(int_roundings)]
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(8), 16);")]
@@ -3367,8 +3171,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(int_roundings)]
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(16));")]
@@ -3582,8 +3384,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".abs(), 10);")]
         #[doc = concat!("assert_eq!((-10", stringify!($SelfT), ").abs(), 10);")]
@@ -3613,8 +3413,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(80), 20", stringify!($UnsignedT), ");")]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($UnsignedT), ");")]
@@ -3656,8 +3454,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".signum(), 1);")]
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".signum(), 0);")]
@@ -3682,8 +3478,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert!(10", stringify!($SelfT), ".is_positive());")]
         #[doc = concat!("assert!(!(-10", stringify!($SelfT), ").is_positive());")]
@@ -3699,8 +3493,6 @@ macro_rules! int_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert!((-10", stringify!($SelfT), ").is_negative());")]
         #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_negative());")]
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index ab2fcff61cd..faa41ddf13c 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -1399,7 +1399,6 @@ macro_rules! from_str_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
             /// ```
             /// use std::str::FromStr;
             ///
@@ -1445,7 +1444,6 @@ macro_rules! from_str_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
             /// ```
             #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str_radix(\"A\", 16), Ok(10));")]
             /// ```
@@ -1478,7 +1476,6 @@ macro_rules! from_str_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
             /// ```
             /// #![feature(int_from_ascii)]
             ///
@@ -1523,7 +1520,6 @@ macro_rules! from_str_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
             /// ```
             /// #![feature(int_from_ascii)]
             ///
diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs
index 3f4791e163e..4460e430aec 100644
--- a/library/core/src/num/saturating.rs
+++ b/library/core/src/num/saturating.rs
@@ -300,8 +300,6 @@ macro_rules! saturating_impl {
 
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// use std::num::Saturating;
         ///
@@ -490,8 +488,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -504,8 +500,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -518,8 +512,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -532,8 +524,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -556,8 +546,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -576,8 +564,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -603,8 +589,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -631,8 +615,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -654,8 +636,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -683,8 +663,6 @@ macro_rules! saturating_int_impl {
             /// Please note that this example is shared between integer types.
             /// Which explains why `i16` is used here.
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -712,8 +690,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -740,8 +716,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -768,8 +742,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -797,8 +769,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -823,8 +793,6 @@ macro_rules! saturating_int_impl {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -860,8 +828,6 @@ macro_rules! saturating_int_impl_signed {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -883,8 +849,6 @@ macro_rules! saturating_int_impl_signed {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -911,8 +875,6 @@ macro_rules! saturating_int_impl_signed {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -934,8 +896,6 @@ macro_rules! saturating_int_impl_signed {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -955,8 +915,6 @@ macro_rules! saturating_int_impl_signed {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -994,8 +952,6 @@ macro_rules! saturating_int_impl_unsigned {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
@@ -1016,8 +972,6 @@ macro_rules! saturating_int_impl_unsigned {
             ///
             /// # Examples
             ///
-            /// Basic usage:
-            ///
             /// ```
             /// use std::num::Saturating;
             ///
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 4ee0e7326b3..079032f2f96 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -27,8 +27,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, 0);")]
         /// ```
@@ -40,8 +38,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($MaxV), ");")]
         /// ```
@@ -62,8 +58,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0b01001100", stringify!($SelfT), ";")]
         /// assert_eq!(n.count_ones(), 3);
@@ -89,8 +83,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
         #[doc = concat!("assert_eq!(zero.count_zeros(), ", stringify!($BITS), ");")]
@@ -114,8 +106,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", stringify!($SelfT), "::MAX >> 2;")]
         /// assert_eq!(n.leading_zeros(), 2);
@@ -141,8 +131,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0b0101000", stringify!($SelfT), ";")]
         /// assert_eq!(n.trailing_zeros(), 3);
@@ -166,8 +154,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = !(", stringify!($SelfT), "::MAX >> 2);")]
         /// assert_eq!(n.leading_ones(), 2);
@@ -192,8 +178,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0b1010111", stringify!($SelfT), ";")]
         /// assert_eq!(n.trailing_ones(), 3);
@@ -219,8 +203,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(uint_bit_width)]
         ///
@@ -242,8 +224,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(isolate_most_least_significant_one)]
         ///
@@ -265,8 +245,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(isolate_most_least_significant_one)]
         ///
@@ -290,8 +268,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", stringify!($SelfT), "::MAX;")]
         ///
@@ -313,8 +289,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $rot_op, stringify!($SelfT), ";")]
         #[doc = concat!("let m = ", $rot_result, ";")]
@@ -338,8 +312,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $rot_result, stringify!($SelfT), ";")]
         #[doc = concat!("let m = ", $rot_op, ";")]
@@ -359,8 +331,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $swap_op, stringify!($SelfT), ";")]
         /// let m = n.swap_bytes();
@@ -381,8 +351,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = ", $swap_op, stringify!($SelfT), ";")]
         /// let m = n.reverse_bits();
@@ -406,8 +374,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -439,8 +405,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -472,8 +436,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -506,8 +468,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("let n = 0x1A", stringify!($SelfT), ";")]
         ///
@@ -538,8 +498,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!(
             "assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(1), ",
@@ -579,8 +537,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).strict_add(1), ", stringify!($SelfT), "::MAX - 1);")]
@@ -647,8 +603,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_signed(2), Some(3));")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_signed(-2), None);")]
@@ -675,8 +629,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_add_signed(2), 3);")]
@@ -708,8 +660,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub(1), Some(0));")]
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);")]
@@ -744,8 +694,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_sub(1), 0);")]
@@ -837,8 +785,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(mixed_integer_ops_unsigned_sub)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(2), None);")]
@@ -866,8 +812,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(unsigned_signed_diff)]
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_signed_diff(2), Some(8));")]
@@ -925,8 +869,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_mul(1), Some(5));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_mul(2), None);")]
@@ -952,8 +894,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_mul(1), 5);")]
@@ -1020,8 +960,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64));")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);")]
@@ -1053,8 +991,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_div(10), 10);")]
@@ -1080,8 +1016,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);")]
@@ -1113,8 +1047,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_div_euclid(10), 10);")]
@@ -1142,8 +1074,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(exact_div)]
         #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), 32);")]
@@ -1184,8 +1114,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(exact_div)]
         #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), 32);")]
@@ -1241,8 +1169,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1));")]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);")]
@@ -1275,8 +1201,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_rem(10), 0);")]
@@ -1302,8 +1226,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));")]
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);")]
@@ -1336,8 +1258,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_rem_euclid(10), 0);")]
@@ -1583,8 +1503,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".checked_neg(), Some(0));")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);")]
@@ -1612,8 +1530,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".strict_neg(), 0);")]
@@ -1640,8 +1556,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10));")]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);")]
@@ -1673,8 +1587,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".strict_shl(4), 0x10);")]
@@ -1737,7 +1649,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
@@ -1762,8 +1673,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1));")]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);")]
@@ -1794,8 +1703,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".strict_shr(4), 0x1);")]
@@ -1858,7 +1765,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
@@ -1883,8 +1789,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);")]
@@ -1925,8 +1829,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(strict_overflow_ops)]
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".strict_pow(5), 32);")]
@@ -1968,8 +1870,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(127), ", stringify!($SelfT), "::MAX);")]
@@ -1988,8 +1888,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_signed(2), 3);")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_signed(-2), 0);")]
@@ -2016,8 +1914,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);")]
         #[doc = concat!("assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);")]
@@ -2036,8 +1932,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(mixed_integer_ops_unsigned_sub)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(2), 0);")]
@@ -2065,8 +1959,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".saturating_mul(10), 20);")]
         #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($SelfT),"::MAX);")]
@@ -2092,8 +1984,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".saturating_div(2), 2);")]
         ///
@@ -2114,8 +2004,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);")]
@@ -2137,8 +2025,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(200", stringify!($SelfT), ".wrapping_add(55), 255);")]
         #[doc = concat!("assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::MAX), 199);")]
@@ -2157,8 +2043,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_add_signed(2), 3);")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_add_signed(-2), ", stringify!($SelfT), "::MAX);")]
@@ -2178,8 +2062,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_sub(100), 0);")]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::MAX), 101);")]
@@ -2198,8 +2080,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(mixed_integer_ops_unsigned_sub)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(2), ", stringify!($SelfT), "::MAX);")]
@@ -2219,8 +2099,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `u8` is used here.
         ///
@@ -2249,8 +2127,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);")]
         /// ```
@@ -2278,8 +2154,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);")]
         /// ```
@@ -2306,8 +2180,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);")]
         /// ```
@@ -2336,8 +2208,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);")]
         /// ```
@@ -2363,8 +2233,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".wrapping_neg(), 0);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_neg(), 1);")]
@@ -2393,8 +2261,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);")]
@@ -2425,8 +2291,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);")]
         #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);")]
@@ -2449,8 +2313,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243);")]
         /// assert_eq!(3u8.wrapping_pow(6), 217);
@@ -2507,8 +2369,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));")]
@@ -2587,8 +2447,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_signed(2), (3, false));")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_signed(-2), (", stringify!($SelfT), "::MAX, true));")]
@@ -2612,8 +2470,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));")]
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));")]
@@ -2683,8 +2539,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(mixed_integer_ops_unsigned_sub)]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(2), (", stringify!($SelfT), "::MAX, true));")]
@@ -2705,8 +2559,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(80), 20", stringify!($SelfT), ");")]
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($SelfT), ");")]
@@ -2738,8 +2590,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `u32` is used here.
         ///
@@ -2767,8 +2617,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `u32` is used here.
         ///
@@ -2800,8 +2648,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types.
         /// Which explains why `u32` is used here.
         ///
@@ -2888,8 +2734,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// Please note that this example is shared between integer types,
         /// which explains why `u32` is used here.
         ///
@@ -2955,8 +2799,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));")]
         /// ```
@@ -2986,8 +2828,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));")]
         /// ```
@@ -3014,8 +2854,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));")]
         /// ```
@@ -3045,8 +2883,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));")]
         /// ```
@@ -3069,8 +2905,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false));")]
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!($SelfT), ", true));")]
@@ -3094,8 +2928,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false));")]
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));")]
@@ -3120,8 +2952,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));")]
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));")]
@@ -3142,8 +2972,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false));")]
         /// assert_eq!(3u8.overflowing_pow(6), (217, true));
@@ -3185,8 +3013,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".pow(5), 32);")]
         /// ```
@@ -3240,7 +3066,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
         /// ```
         #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")]
         /// ```
@@ -3282,8 +3107,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type")]
         /// ```
@@ -3310,8 +3133,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type")]
         /// ```
@@ -3336,8 +3157,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(int_roundings)]
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".div_floor(4), 1);")]
@@ -3359,8 +3178,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".div_ceil(4), 2);")]
         /// ```
@@ -3394,8 +3211,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(8), 16);")]
         #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".next_multiple_of(8), 24);")]
@@ -3419,8 +3234,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(16));")]
         #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(24));")]
@@ -3448,8 +3261,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert!(6_", stringify!($SelfT), ".is_multiple_of(2));")]
         #[doc = concat!("assert!(!5_", stringify!($SelfT), ".is_multiple_of(2));")]
@@ -3473,8 +3284,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert!(16", stringify!($SelfT), ".is_power_of_two());")]
         #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_power_of_two());")]
@@ -3517,8 +3326,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2);")]
         #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);")]
@@ -3540,8 +3347,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_next_power_of_two(), Some(2));")]
         #[doc = concat!("assert_eq!(3", stringify!($SelfT), ".checked_next_power_of_two(), Some(4));")]
@@ -3562,8 +3367,6 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage:
-        ///
         /// ```
         /// #![feature(wrapping_next_power_of_two)]
         ///
diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs
index 0671a8467e8..0364c664ba5 100644
--- a/src/bootstrap/src/bin/rustc.rs
+++ b/src/bootstrap/src/bin/rustc.rs
@@ -151,18 +151,6 @@ fn main() {
             cmd.arg("--sysroot").arg(&sysroot);
         }
 
-        // If we're compiling specifically the `panic_abort` crate then we pass
-        // the `-C panic=abort` option. Note that we do not do this for any
-        // other crate intentionally as this is the only crate for now that we
-        // ship with panic=abort.
-        //
-        // This... is a bit of a hack how we detect this. Ideally this
-        // information should be encoded in the crate I guess? Would likely
-        // require an RFC amendment to RFC 1513, however.
-        if crate_name == Some("panic_abort") {
-            cmd.arg("-C").arg("panic=abort");
-        }
-
         let crate_type = parse_value_from_args(&orig_args, "--crate-type");
         // `-Ztls-model=initial-exec` must not be applied to proc-macros, see
         // issue https://github.com/rust-lang/rust/issues/100530
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 408ef611ee5..c0a9d8c84f6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -2432,20 +2432,6 @@ pub(crate) enum ConstantKind {
     Infer,
 }
 
-impl Constant {
-    pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String {
-        self.kind.expr(tcx)
-    }
-
-    pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
-        self.kind.value(tcx)
-    }
-
-    pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
-        self.kind.is_literal(tcx)
-    }
-}
-
 impl ConstantKind {
     pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String {
         match *self {
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index fb2b45802a6..606a9113908 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -439,24 +439,20 @@ impl CratesIndexPart {
         let content =
             format!("<h1>List of all crates</h1><ul class=\"all-items\">{DELIMITER}</ul>");
         let template = layout::render(layout, &page, "", content, style_files);
-        match SortedTemplate::from_template(&template, DELIMITER) {
-            Ok(template) => template,
-            Err(e) => panic!(
-                "Object Replacement Character (U+FFFC) should not appear in the --index-page: {e}"
-            ),
-        }
+        SortedTemplate::from_template(&template, DELIMITER)
+            .expect("Object Replacement Character (U+FFFC) should not appear in the --index-page")
     }
 
     /// Might return parts that are duplicate with ones in prexisting index.html
     fn get(crate_name: &str, external_crates: &[String]) -> Result<PartsAndLocations<Self>, Error> {
         let mut ret = PartsAndLocations::default();
-        let path = PathBuf::from("index.html");
+        let path = Path::new("index.html");
         for crate_name in external_crates.iter().map(|s| s.as_str()).chain(once(crate_name)) {
             let part = format!(
                 "<li><a href=\"{trailing_slash}index.html\">{crate_name}</a></li>",
                 trailing_slash = ensure_trailing_slash(crate_name),
             );
-            ret.push(path.clone(), part);
+            ret.push(path.to_path_buf(), part);
         }
         Ok(ret)
     }
@@ -737,7 +733,7 @@ impl TraitAliasPart {
                 },
             };
 
-            let implementors = imps
+            let mut implementors = imps
                 .iter()
                 .filter_map(|imp| {
                     // If the trait and implementation are in the same crate, then
@@ -759,12 +755,12 @@ impl TraitAliasPart {
                         })
                     }
                 })
-                .collect::<Vec<_>>();
+                .peekable();
 
             // Only create a js file if we have impls to add to it. If the trait is
             // documented locally though we always create the file to avoid dead
             // links.
-            if implementors.is_empty() && !cache.paths.contains_key(&did) {
+            if implementors.peek().is_none() && !cache.paths.contains_key(&did) {
                 continue;
             }
 
@@ -775,11 +771,7 @@ impl TraitAliasPart {
             path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1]));
 
             let part = OrderedJson::array_sorted(
-                implementors
-                    .iter()
-                    .map(OrderedJson::serialize)
-                    .collect::<Result<Vec<_>, _>>()
-                    .unwrap(),
+                implementors.map(|implementor| OrderedJson::serialize(implementor).unwrap()),
             );
             path_parts.push(path, OrderedJson::array_unsorted([crate_name_json, &part]));
         }
@@ -874,9 +866,8 @@ impl<'item> DocVisitor<'item> for TypeImplCollector<'_, '_, 'item> {
             let impl_ = cache
                 .impls
                 .get(&target_did)
-                .map(|v| &v[..])
-                .unwrap_or_default()
-                .iter()
+                .into_iter()
+                .flatten()
                 .map(|impl_| {
                     (impl_.impl_item.item_id, AliasedTypeImpl { impl_, type_aliases: Vec::new() })
                 })
@@ -891,14 +882,8 @@ impl<'item> DocVisitor<'item> for TypeImplCollector<'_, '_, 'item> {
         // Exclude impls that are directly on this type. They're already in the HTML.
         // Some inlining scenarios can cause there to be two versions of the same
         // impl: one on the type alias and one on the underlying target type.
-        let mut seen_impls: FxHashSet<ItemId> = cache
-            .impls
-            .get(&self_did)
-            .map(|s| &s[..])
-            .unwrap_or_default()
-            .iter()
-            .map(|i| i.impl_item.item_id)
-            .collect();
+        let mut seen_impls: FxHashSet<ItemId> =
+            cache.impls.get(&self_did).into_iter().flatten().map(|i| i.impl_item.item_id).collect();
         for (impl_item_id, aliased_type_impl) in &mut aliased_type.impl_ {
             // Only include this impl if it actually unifies with this alias.
             // Synthetic impls are not included; those are also included in the HTML.
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index cb4c1f7fbc0..abad6e48029 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -11,7 +11,7 @@ use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
 use rustc_metadata::rendered_const;
 use rustc_middle::{bug, ty};
-use rustc_span::{Pos, Symbol, kw};
+use rustc_span::{Pos, kw, sym};
 use rustdoc_json_types::*;
 use thin_vec::ThinVec;
 
@@ -66,47 +66,16 @@ impl JsonRenderer<'_> {
             id,
             crate_id: item_id.krate().as_u32(),
             name: name.map(|sym| sym.to_string()),
-            span: span.and_then(|span| self.convert_span(span)),
-            visibility: self.convert_visibility(visibility),
+            span: span.and_then(|span| span.into_json(self)),
+            visibility: visibility.into_json(self),
             docs,
             attrs,
-            deprecation: deprecation.map(from_deprecation),
+            deprecation: deprecation.into_json(self),
             inner,
             links,
         })
     }
 
-    fn convert_span(&self, span: clean::Span) -> Option<Span> {
-        match span.filename(self.sess()) {
-            rustc_span::FileName::Real(name) => {
-                if let Some(local_path) = name.into_local_path() {
-                    let hi = span.hi(self.sess());
-                    let lo = span.lo(self.sess());
-                    Some(Span {
-                        filename: local_path,
-                        begin: (lo.line, lo.col.to_usize() + 1),
-                        end: (hi.line, hi.col.to_usize() + 1),
-                    })
-                } else {
-                    None
-                }
-            }
-            _ => None,
-        }
-    }
-
-    fn convert_visibility(&self, v: Option<ty::Visibility<DefId>>) -> Visibility {
-        match v {
-            None => Visibility::Default,
-            Some(ty::Visibility::Public) => Visibility::Public,
-            Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
-            Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
-                parent: self.id_from_item_default(did.into()),
-                path: self.tcx.def_path(did).to_string_no_crate_verbose(),
-            },
-        }
-    }
-
     fn ids(&self, items: &[clean::Item]) -> Vec<Id> {
         items
             .iter()
@@ -140,11 +109,29 @@ where
     }
 }
 
+impl<T, U> FromClean<Box<T>> for U
+where
+    U: FromClean<T>,
+{
+    fn from_clean(opt: &Box<T>, renderer: &JsonRenderer<'_>) -> Self {
+        opt.as_ref().into_json(renderer)
+    }
+}
+
+impl<T, U> FromClean<Option<T>> for Option<U>
+where
+    U: FromClean<T>,
+{
+    fn from_clean(opt: &Option<T>, renderer: &JsonRenderer<'_>) -> Self {
+        opt.as_ref().map(|x| x.into_json(renderer))
+    }
+}
+
 impl<T, U> FromClean<Vec<T>> for Vec<U>
 where
     U: FromClean<T>,
 {
-    fn from_clean(items: &Vec<T>, renderer: &JsonRenderer<'_>) -> Vec<U> {
+    fn from_clean(items: &Vec<T>, renderer: &JsonRenderer<'_>) -> Self {
         items.iter().map(|i| i.into_json(renderer)).collect()
     }
 }
@@ -153,20 +140,57 @@ impl<T, U> FromClean<ThinVec<T>> for Vec<U>
 where
     U: FromClean<T>,
 {
-    fn from_clean(items: &ThinVec<T>, renderer: &JsonRenderer<'_>) -> Vec<U> {
+    fn from_clean(items: &ThinVec<T>, renderer: &JsonRenderer<'_>) -> Self {
         items.iter().map(|i| i.into_json(renderer)).collect()
     }
 }
 
-pub(crate) fn from_deprecation(deprecation: attrs::Deprecation) -> Deprecation {
-    let attrs::Deprecation { since, note, suggestion: _ } = deprecation;
-    let since = match since {
-        DeprecatedSince::RustcVersion(version) => Some(version.to_string()),
-        DeprecatedSince::Future => Some("TBD".to_owned()),
-        DeprecatedSince::NonStandard(since) => Some(since.to_string()),
-        DeprecatedSince::Unspecified | DeprecatedSince::Err => None,
-    };
-    Deprecation { since, note: note.map(|s| s.to_string()) }
+impl FromClean<clean::Span> for Option<Span> {
+    fn from_clean(span: &clean::Span, renderer: &JsonRenderer<'_>) -> Self {
+        match span.filename(renderer.sess()) {
+            rustc_span::FileName::Real(name) => {
+                if let Some(local_path) = name.into_local_path() {
+                    let hi = span.hi(renderer.sess());
+                    let lo = span.lo(renderer.sess());
+                    Some(Span {
+                        filename: local_path,
+                        begin: (lo.line, lo.col.to_usize() + 1),
+                        end: (hi.line, hi.col.to_usize() + 1),
+                    })
+                } else {
+                    None
+                }
+            }
+            _ => None,
+        }
+    }
+}
+
+impl FromClean<Option<ty::Visibility<DefId>>> for Visibility {
+    fn from_clean(v: &Option<ty::Visibility<DefId>>, renderer: &JsonRenderer<'_>) -> Self {
+        match v {
+            None => Visibility::Default,
+            Some(ty::Visibility::Public) => Visibility::Public,
+            Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
+            Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
+                parent: renderer.id_from_item_default((*did).into()),
+                path: renderer.tcx.def_path(*did).to_string_no_crate_verbose(),
+            },
+        }
+    }
+}
+
+impl FromClean<attrs::Deprecation> for Deprecation {
+    fn from_clean(deprecation: &attrs::Deprecation, _renderer: &JsonRenderer<'_>) -> Self {
+        let attrs::Deprecation { since, note, suggestion: _ } = deprecation;
+        let since = match since {
+            DeprecatedSince::RustcVersion(version) => Some(version.to_string()),
+            DeprecatedSince::Future => Some("TBD".to_string()),
+            DeprecatedSince::NonStandard(since) => Some(since.to_string()),
+            DeprecatedSince::Unspecified | DeprecatedSince::Err => None,
+        };
+        Deprecation { since, note: note.map(|sym| sym.to_string()) }
+    }
 }
 
 impl FromClean<clean::GenericArgs> for Option<Box<GenericArgs>> {
@@ -182,7 +206,7 @@ impl FromClean<clean::GenericArgs> for Option<Box<GenericArgs>> {
             },
             Parenthesized { inputs, output } => GenericArgs::Parenthesized {
                 inputs: inputs.into_json(renderer),
-                output: output.as_ref().map(|a| a.as_ref().into_json(renderer)),
+                output: output.into_json(renderer),
             },
             ReturnTypeNotation => GenericArgs::ReturnTypeNotation,
         }))
@@ -193,7 +217,7 @@ impl FromClean<clean::GenericArg> for GenericArg {
     fn from_clean(arg: &clean::GenericArg, renderer: &JsonRenderer<'_>) -> Self {
         use clean::GenericArg::*;
         match arg {
-            Lifetime(l) => GenericArg::Lifetime(convert_lifetime(l)),
+            Lifetime(l) => GenericArg::Lifetime(l.into_json(renderer)),
             Type(t) => GenericArg::Type(t.into_json(renderer)),
             Const(box c) => GenericArg::Const(c.into_json(renderer)),
             Infer => GenericArg::Infer,
@@ -201,17 +225,6 @@ impl FromClean<clean::GenericArg> for GenericArg {
     }
 }
 
-impl FromClean<clean::Constant> for Constant {
-    // FIXME(generic_const_items): Add support for generic const items.
-    fn from_clean(constant: &clean::Constant, renderer: &JsonRenderer<'_>) -> Self {
-        let tcx = renderer.tcx;
-        let expr = constant.expr(tcx);
-        let value = constant.value(tcx);
-        let is_literal = constant.is_literal(tcx);
-        Constant { expr, value, is_literal }
-    }
-}
-
 impl FromClean<clean::ConstantKind> for Constant {
     // FIXME(generic_const_items): Add support for generic const items.
     fn from_clean(constant: &clean::ConstantKind, renderer: &JsonRenderer<'_>) -> Self {
@@ -259,21 +272,25 @@ fn from_clean_item(item: &clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum
         StructFieldItem(f) => ItemEnum::StructField(f.into_json(renderer)),
         EnumItem(e) => ItemEnum::Enum(e.into_json(renderer)),
         VariantItem(v) => ItemEnum::Variant(v.into_json(renderer)),
-        FunctionItem(f) => ItemEnum::Function(from_function(f, true, header.unwrap(), renderer)),
+        FunctionItem(f) => {
+            ItemEnum::Function(from_clean_function(f, true, header.unwrap(), renderer))
+        }
         ForeignFunctionItem(f, _) => {
-            ItemEnum::Function(from_function(f, false, header.unwrap(), renderer))
+            ItemEnum::Function(from_clean_function(f, false, header.unwrap(), renderer))
         }
-        TraitItem(t) => ItemEnum::Trait(t.as_ref().into_json(renderer)),
+        TraitItem(t) => ItemEnum::Trait(t.into_json(renderer)),
         TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_json(renderer)),
-        MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)),
+        MethodItem(m, _) => {
+            ItemEnum::Function(from_clean_function(m, true, header.unwrap(), renderer))
+        }
         RequiredMethodItem(m) => {
-            ItemEnum::Function(from_function(m, false, header.unwrap(), renderer))
+            ItemEnum::Function(from_clean_function(m, false, header.unwrap(), renderer))
         }
-        ImplItem(i) => ItemEnum::Impl(i.as_ref().into_json(renderer)),
-        StaticItem(s) => ItemEnum::Static(convert_static(s, &rustc_hir::Safety::Safe, renderer)),
-        ForeignStaticItem(s, safety) => ItemEnum::Static(convert_static(s, safety, renderer)),
+        ImplItem(i) => ItemEnum::Impl(i.into_json(renderer)),
+        StaticItem(s) => ItemEnum::Static(from_clean_static(s, rustc_hir::Safety::Safe, renderer)),
+        ForeignStaticItem(s, safety) => ItemEnum::Static(from_clean_static(s, *safety, renderer)),
         ForeignTypeItem => ItemEnum::ExternType,
-        TypeAliasItem(t) => ItemEnum::TypeAlias(t.as_ref().into_json(renderer)),
+        TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_json(renderer)),
         // FIXME(generic_const_items): Add support for generic free consts
         ConstantItem(ci) => ItemEnum::Constant {
             type_: ci.type_.into_json(renderer),
@@ -289,7 +306,7 @@ fn from_clean_item(item: &clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum
         }
         // FIXME(generic_const_items): Add support for generic associated consts.
         RequiredAssocConstItem(_generics, ty) => {
-            ItemEnum::AssocConst { type_: ty.as_ref().into_json(renderer), value: None }
+            ItemEnum::AssocConst { type_: ty.into_json(renderer), value: None }
         }
         // FIXME(generic_const_items): Add support for generic associated consts.
         ProvidedAssocConstItem(ci) | ImplAssocConstItem(ci) => ItemEnum::AssocConst {
@@ -361,32 +378,38 @@ impl FromClean<clean::Union> for Union {
     }
 }
 
-pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> FunctionHeader {
-    FunctionHeader {
-        is_async: header.is_async(),
-        is_const: header.is_const(),
-        is_unsafe: header.is_unsafe(),
-        abi: convert_abi(header.abi),
+impl FromClean<rustc_hir::FnHeader> for FunctionHeader {
+    fn from_clean(header: &rustc_hir::FnHeader, renderer: &JsonRenderer<'_>) -> Self {
+        FunctionHeader {
+            is_async: header.is_async(),
+            is_const: header.is_const(),
+            is_unsafe: header.is_unsafe(),
+            abi: header.abi.into_json(renderer),
+        }
     }
 }
 
-fn convert_abi(a: ExternAbi) -> Abi {
-    match a {
-        ExternAbi::Rust => Abi::Rust,
-        ExternAbi::C { unwind } => Abi::C { unwind },
-        ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
-        ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
-        ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
-        ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
-        ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
-        ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
-        ExternAbi::System { unwind } => Abi::System { unwind },
-        _ => Abi::Other(a.to_string()),
+impl FromClean<ExternAbi> for Abi {
+    fn from_clean(a: &ExternAbi, _renderer: &JsonRenderer<'_>) -> Self {
+        match *a {
+            ExternAbi::Rust => Abi::Rust,
+            ExternAbi::C { unwind } => Abi::C { unwind },
+            ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
+            ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
+            ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
+            ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
+            ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
+            ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
+            ExternAbi::System { unwind } => Abi::System { unwind },
+            _ => Abi::Other(a.to_string()),
+        }
     }
 }
 
-fn convert_lifetime(l: &clean::Lifetime) -> String {
-    l.0.to_string()
+impl FromClean<clean::Lifetime> for String {
+    fn from_clean(l: &clean::Lifetime, _renderer: &JsonRenderer<'_>) -> String {
+        l.0.to_string()
+    }
 }
 
 impl FromClean<clean::Generics> for Generics {
@@ -411,16 +434,16 @@ impl FromClean<clean::GenericParamDefKind> for GenericParamDefKind {
     fn from_clean(kind: &clean::GenericParamDefKind, renderer: &JsonRenderer<'_>) -> Self {
         use clean::GenericParamDefKind::*;
         match kind {
-            Lifetime { outlives } => GenericParamDefKind::Lifetime {
-                outlives: outlives.into_iter().map(convert_lifetime).collect(),
-            },
+            Lifetime { outlives } => {
+                GenericParamDefKind::Lifetime { outlives: outlives.into_json(renderer) }
+            }
             Type { bounds, default, synthetic } => GenericParamDefKind::Type {
                 bounds: bounds.into_json(renderer),
-                default: default.as_ref().map(|x| x.as_ref().into_json(renderer)),
+                default: default.into_json(renderer),
                 is_synthetic: *synthetic,
             },
             Const { ty, default, synthetic: _ } => GenericParamDefKind::Const {
-                type_: ty.as_ref().into_json(renderer),
+                type_: ty.into_json(renderer),
                 default: default.as_ref().map(|x| x.as_ref().clone()),
             },
         }
@@ -434,45 +457,14 @@ impl FromClean<clean::WherePredicate> for WherePredicate {
             BoundPredicate { ty, bounds, bound_params } => WherePredicate::BoundPredicate {
                 type_: ty.into_json(renderer),
                 bounds: bounds.into_json(renderer),
-                generic_params: bound_params
-                    .iter()
-                    .map(|x| {
-                        let name = x.name.to_string();
-                        let kind = match &x.kind {
-                            clean::GenericParamDefKind::Lifetime { outlives } => {
-                                GenericParamDefKind::Lifetime {
-                                    outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(),
-                                }
-                            }
-                            clean::GenericParamDefKind::Type { bounds, default, synthetic } => {
-                                GenericParamDefKind::Type {
-                                    bounds: bounds
-                                        .into_iter()
-                                        .map(|bound| bound.into_json(renderer))
-                                        .collect(),
-                                    default: default
-                                        .as_ref()
-                                        .map(|ty| ty.as_ref().into_json(renderer)),
-                                    is_synthetic: *synthetic,
-                                }
-                            }
-                            clean::GenericParamDefKind::Const { ty, default, synthetic: _ } => {
-                                GenericParamDefKind::Const {
-                                    type_: ty.as_ref().into_json(renderer),
-                                    default: default.as_ref().map(|d| d.as_ref().clone()),
-                                }
-                            }
-                        };
-                        GenericParamDef { name, kind }
-                    })
-                    .collect(),
+                generic_params: bound_params.into_json(renderer),
             },
             RegionPredicate { lifetime, bounds } => WherePredicate::LifetimePredicate {
-                lifetime: convert_lifetime(lifetime),
+                lifetime: lifetime.into_json(renderer),
                 outlives: bounds
                     .iter()
                     .map(|bound| match bound {
-                        clean::GenericBound::Outlives(lt) => convert_lifetime(lt),
+                        clean::GenericBound::Outlives(lt) => lt.into_json(renderer),
                         _ => bug!("found non-outlives-bound on lifetime predicate"),
                     })
                     .collect(),
@@ -496,15 +488,15 @@ impl FromClean<clean::GenericBound> for GenericBound {
                 GenericBound::TraitBound {
                     trait_: trait_.into_json(renderer),
                     generic_params: generic_params.into_json(renderer),
-                    modifier: from_trait_bound_modifier(modifier),
+                    modifier: modifier.into_json(renderer),
                 }
             }
-            Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
+            Outlives(lifetime) => GenericBound::Outlives(lifetime.into_json(renderer)),
             Use(args) => GenericBound::Use(
                 args.iter()
                     .map(|arg| match arg {
                         clean::PreciseCapturingArg::Lifetime(lt) => {
-                            PreciseCapturingArg::Lifetime(convert_lifetime(lt))
+                            PreciseCapturingArg::Lifetime(lt.into_json(renderer))
                         }
                         clean::PreciseCapturingArg::Param(param) => {
                             PreciseCapturingArg::Param(param.to_string())
@@ -516,19 +508,22 @@ impl FromClean<clean::GenericBound> for GenericBound {
     }
 }
 
-pub(crate) fn from_trait_bound_modifier(
-    modifiers: &rustc_hir::TraitBoundModifiers,
-) -> TraitBoundModifier {
-    use rustc_hir as hir;
-    let hir::TraitBoundModifiers { constness, polarity } = modifiers;
-    match (constness, polarity) {
-        (hir::BoundConstness::Never, hir::BoundPolarity::Positive) => TraitBoundModifier::None,
-        (hir::BoundConstness::Never, hir::BoundPolarity::Maybe(_)) => TraitBoundModifier::Maybe,
-        (hir::BoundConstness::Maybe(_), hir::BoundPolarity::Positive) => {
-            TraitBoundModifier::MaybeConst
+impl FromClean<rustc_hir::TraitBoundModifiers> for TraitBoundModifier {
+    fn from_clean(
+        modifiers: &rustc_hir::TraitBoundModifiers,
+        _renderer: &JsonRenderer<'_>,
+    ) -> Self {
+        use rustc_hir as hir;
+        let hir::TraitBoundModifiers { constness, polarity } = modifiers;
+        match (constness, polarity) {
+            (hir::BoundConstness::Never, hir::BoundPolarity::Positive) => TraitBoundModifier::None,
+            (hir::BoundConstness::Never, hir::BoundPolarity::Maybe(_)) => TraitBoundModifier::Maybe,
+            (hir::BoundConstness::Maybe(_), hir::BoundPolarity::Positive) => {
+                TraitBoundModifier::MaybeConst
+            }
+            // FIXME: Fill out the rest of this matrix.
+            _ => TraitBoundModifier::None,
         }
-        // FIXME: Fill out the rest of this matrix.
-        _ => TraitBoundModifier::None,
     }
 }
 
@@ -542,35 +537,35 @@ impl FromClean<clean::Type> for Type {
         match ty {
             clean::Type::Path { path } => Type::ResolvedPath(path.into_json(renderer)),
             clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
-                lifetime: lt.as_ref().map(convert_lifetime),
+                lifetime: lt.into_json(renderer),
                 traits: bounds.into_json(renderer),
             }),
             Generic(s) => Type::Generic(s.to_string()),
             // FIXME: add dedicated variant to json Type?
             SelfTy => Type::Generic("Self".to_owned()),
             Primitive(p) => Type::Primitive(p.as_sym().to_string()),
-            BareFunction(f) => Type::FunctionPointer(Box::new(f.as_ref().into_json(renderer))),
+            BareFunction(f) => Type::FunctionPointer(Box::new(f.into_json(renderer))),
             Tuple(t) => Type::Tuple(t.into_json(renderer)),
-            Slice(t) => Type::Slice(Box::new(t.as_ref().into_json(renderer))),
+            Slice(t) => Type::Slice(Box::new(t.into_json(renderer))),
             Array(t, s) => {
-                Type::Array { type_: Box::new(t.as_ref().into_json(renderer)), len: s.to_string() }
+                Type::Array { type_: Box::new(t.into_json(renderer)), len: s.to_string() }
             }
             clean::Type::Pat(t, p) => Type::Pat {
-                type_: Box::new(t.as_ref().into_json(renderer)),
+                type_: Box::new(t.into_json(renderer)),
                 __pat_unstable_do_not_use: p.to_string(),
             },
             ImplTrait(g) => Type::ImplTrait(g.into_json(renderer)),
             Infer => Type::Infer,
             RawPointer(mutability, type_) => Type::RawPointer {
                 is_mutable: *mutability == ast::Mutability::Mut,
-                type_: Box::new(type_.as_ref().into_json(renderer)),
+                type_: Box::new(type_.into_json(renderer)),
             },
             BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef {
-                lifetime: lifetime.as_ref().map(convert_lifetime),
+                lifetime: lifetime.into_json(renderer),
                 is_mutable: *mutability == ast::Mutability::Mut,
-                type_: Box::new(type_.as_ref().into_json(renderer)),
+                type_: Box::new(type_.into_json(renderer)),
             },
-            QPath(qpath) => qpath.as_ref().into_json(renderer),
+            QPath(qpath) => qpath.into_json(renderer),
             // FIXME(unsafe_binder): Implement rustdoc-json.
             UnsafeBinder(_) => todo!(),
         }
@@ -578,7 +573,7 @@ impl FromClean<clean::Type> for Type {
 }
 
 impl FromClean<clean::Path> for Path {
-    fn from_clean(path: &clean::Path, renderer: &JsonRenderer<'_>) -> Path {
+    fn from_clean(path: &clean::Path, renderer: &JsonRenderer<'_>) -> Self {
         Path {
             path: path.whole_name(),
             id: renderer.id_from_item_default(path.def_id().into()),
@@ -608,13 +603,13 @@ impl FromClean<clean::QPathData> for Type {
             name: assoc.name.to_string(),
             args: assoc.args.into_json(renderer),
             self_type: Box::new(self_type.into_json(renderer)),
-            trait_: trait_.as_ref().map(|trait_| trait_.into_json(renderer)),
+            trait_: trait_.into_json(renderer),
         }
     }
 }
 
 impl FromClean<clean::Term> for Term {
-    fn from_clean(term: &clean::Term, renderer: &JsonRenderer<'_>) -> Term {
+    fn from_clean(term: &clean::Term, renderer: &JsonRenderer<'_>) -> Self {
         match term {
             clean::Term::Type(ty) => Term::Type(ty.into_json(renderer)),
             clean::Term::Constant(c) => Term::Constant(c.into_json(renderer)),
@@ -630,7 +625,7 @@ impl FromClean<clean::BareFunctionDecl> for FunctionPointer {
                 is_unsafe: safety.is_unsafe(),
                 is_const: false,
                 is_async: false,
-                abi: convert_abi(*abi),
+                abi: abi.into_json(renderer),
             },
             generic_params: generic_params.into_json(renderer),
             sig: decl.into_json(renderer),
@@ -709,17 +704,17 @@ impl FromClean<clean::Impl> for Impl {
                 .into_iter()
                 .map(|x| x.to_string())
                 .collect(),
-            trait_: trait_.as_ref().map(|path| path.into_json(renderer)),
+            trait_: trait_.into_json(renderer),
             for_: for_.into_json(renderer),
             items: renderer.ids(&items),
             is_negative,
             is_synthetic,
-            blanket_impl: blanket_impl.map(|x| x.as_ref().into_json(renderer)),
+            blanket_impl: blanket_impl.map(|x| x.into_json(renderer)),
         }
     }
 }
 
-pub(crate) fn from_function(
+pub(crate) fn from_clean_function(
     clean::Function { decl, generics }: &clean::Function,
     has_body: bool,
     header: rustc_hir::FnHeader,
@@ -728,7 +723,7 @@ pub(crate) fn from_function(
     Function {
         sig: decl.into_json(renderer),
         generics: generics.into_json(renderer),
-        header: from_fn_header(&header),
+        header: header.into_json(renderer),
         has_body,
     }
 }
@@ -750,7 +745,7 @@ impl FromClean<clean::Variant> for Variant {
     fn from_clean(variant: &clean::Variant, renderer: &JsonRenderer<'_>) -> Self {
         use clean::VariantKind::*;
 
-        let discriminant = variant.discriminant.as_ref().map(|d| d.into_json(renderer));
+        let discriminant = variant.discriminant.into_json(renderer);
 
         let kind = match &variant.kind {
             CLike => VariantKind::Plain,
@@ -783,10 +778,7 @@ impl FromClean<clean::Import> for Use {
         use clean::ImportKind::*;
         let (name, is_glob) = match import.kind {
             Simple(s) => (s.to_string(), false),
-            Glob => (
-                import.source.path.last_opt().unwrap_or_else(|| Symbol::intern("*")).to_string(),
-                true,
-            ),
+            Glob => (import.source.path.last_opt().unwrap_or(sym::asterisk).to_string(), true),
         };
         Use {
             source: import.source.path.whole_name(),
@@ -798,20 +790,22 @@ impl FromClean<clean::Import> for Use {
 }
 
 impl FromClean<clean::ProcMacro> for ProcMacro {
-    fn from_clean(mac: &clean::ProcMacro, _renderer: &JsonRenderer<'_>) -> Self {
+    fn from_clean(mac: &clean::ProcMacro, renderer: &JsonRenderer<'_>) -> Self {
         ProcMacro {
-            kind: from_macro_kind(mac.kind),
+            kind: mac.kind.into_json(renderer),
             helpers: mac.helpers.iter().map(|x| x.to_string()).collect(),
         }
     }
 }
 
-pub(crate) fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind {
-    use rustc_span::hygiene::MacroKind::*;
-    match kind {
-        Bang => MacroKind::Bang,
-        Attr => MacroKind::Attr,
-        Derive => MacroKind::Derive,
+impl FromClean<rustc_span::hygiene::MacroKind> for MacroKind {
+    fn from_clean(kind: &rustc_span::hygiene::MacroKind, _renderer: &JsonRenderer<'_>) -> Self {
+        use rustc_span::hygiene::MacroKind::*;
+        match kind {
+            Bang => MacroKind::Bang,
+            Attr => MacroKind::Attr,
+            Derive => MacroKind::Derive,
+        }
     }
 }
 
@@ -822,9 +816,9 @@ impl FromClean<clean::TypeAlias> for TypeAlias {
     }
 }
 
-fn convert_static(
+fn from_clean_static(
     stat: &clean::Static,
-    safety: &rustc_hir::Safety,
+    safety: rustc_hir::Safety,
     renderer: &JsonRenderer<'_>,
 ) -> Static {
     let tcx = renderer.tcx;
diff --git a/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs
index 289b6b915d4..d3c39686976 100644
--- a/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_ast::attr::AttributeExt as _;
 use rustc_ast::token::CommentKind;
 use rustc_errors::Applicability;
 use rustc_hir::{AttrStyle, Attribute};
@@ -43,13 +44,19 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &F
                 "looks like a footnote ref, but has no matching footnote",
                 |diag| {
                     if this_fragment.kind == DocFragmentKind::SugaredDoc {
-                        let (doc_attr, (_, doc_attr_comment_kind)) = attrs
+                        let (doc_attr, (_, doc_attr_comment_kind), attr_style) = attrs
                             .iter()
                             .filter(|attr| attr.span().overlaps(this_fragment.span))
                             .rev()
-                            .find_map(|attr| Some((attr, attr.doc_str_and_comment_kind()?)))
+                            .find_map(|attr| {
+                                Some((
+                                    attr,
+                                    attr.doc_str_and_comment_kind()?,
+                                    attr.doc_resolution_scope()?,
+                                ))
+                            })
                             .unwrap();
-                        let (to_add, terminator) = match (doc_attr_comment_kind, doc_attr.style()) {
+                        let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) {
                             (CommentKind::Line, AttrStyle::Outer) => ("\n///\n/// ", ""),
                             (CommentKind::Line, AttrStyle::Inner) => ("\n//!\n//! ", ""),
                             (CommentKind::Block, AttrStyle::Outer) => ("\n/** ", " */"),
diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
index 029da1c1898..60e8e16e25e 100644
--- a/src/tools/compiletest/src/runtest/run_make.rs
+++ b/src/tools/compiletest/src/runtest/run_make.rs
@@ -221,6 +221,10 @@ impl TestCx<'_> {
             cmd.env("REMOTE_TEST_CLIENT", remote_test_client);
         }
 
+        if let Some(runner) = &self.config.runner {
+            cmd.env("RUNNER", runner);
+        }
+
         // We don't want RUSTFLAGS set from the outside to interfere with
         // compiler flags set in the test cases:
         cmd.env_remove("RUSTFLAGS");
diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs
index 60e711d3402..b95f3a5cfe5 100644
--- a/src/tools/run-make-support/src/run.rs
+++ b/src/tools/run-make-support/src/run.rs
@@ -1,4 +1,4 @@
-use std::ffi::OsStr;
+use std::ffi::{OsStr, OsString};
 use std::path::PathBuf;
 use std::{env, panic};
 
@@ -22,6 +22,20 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
         cmd.arg("0");
         cmd.arg(bin_path);
         cmd
+    } else if let Ok(runner) = std::env::var("RUNNER") {
+        let mut args = split_maybe_args(&runner);
+
+        let prog = args.remove(0);
+        let mut cmd = Command::new(prog);
+
+        for arg in args {
+            cmd.arg(arg);
+        }
+
+        cmd.arg("--");
+        cmd.arg(bin_path);
+
+        cmd
     } else {
         Command::new(bin_path)
     };
@@ -92,3 +106,12 @@ pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command {
     command.env("LC_ALL", "C"); // force english locale
     command
 }
+
+fn split_maybe_args(s: &str) -> Vec<OsString> {
+    // FIXME(132599): implement proper env var/shell argument splitting.
+    s.split(' ')
+        .filter_map(|s| {
+            if s.chars().all(|c| c.is_whitespace()) { None } else { Some(OsString::from(s)) }
+        })
+        .collect()
+}
diff --git a/tests/codegen/asm/critical.rs b/tests/codegen/asm/critical.rs
index 8c039900cab..0f29d7c69b4 100644
--- a/tests/codegen/asm/critical.rs
+++ b/tests/codegen/asm/critical.rs
@@ -1,6 +1,5 @@
 //@ only-x86_64
 //@ compile-flags: -C no-prepopulate-passes
-#![feature(asm_goto)]
 #![feature(asm_goto_with_outputs)]
 #![crate_type = "lib"]
 use std::arch::asm;
diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs
index 63904bea622..426d65b7af3 100644
--- a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs
+++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs
@@ -3,7 +3,8 @@
 // prevent the creation of a functional binary.
 // See https://github.com/rust-lang/rust/pull/49878
 
-//@ ignore-cross-compile
+//@ needs-target-std
+//@ ignore-android: FIXME(#142855)
 
 use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name};
 
diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs
index 6875ef9ddc0..3348651d501 100644
--- a/tests/run-make/fmt-write-bloat/rmake.rs
+++ b/tests/run-make/fmt-write-bloat/rmake.rs
@@ -15,14 +15,9 @@
 //! `NO_DEBUG_ASSERTIONS=1`). If debug assertions are disabled, then we can check for the absence of
 //! additional `usize` formatting and padding related symbols.
 
-//@ ignore-windows
-// Reason:
-// - MSVC targets really need to parse the .pdb file (aka the debug information).
-//   On Windows there's an API for that (dbghelp) which maybe we can use
-// - MinGW targets have a lot of symbols included in their runtime which we can't avoid.
-//   We would need to make the symbols we're looking for more specific for this test to work.
 //@ ignore-cross-compile
 
+use run_make_support::artifact_names::bin_name;
 use run_make_support::env::no_debug_assertions;
 use run_make_support::rustc;
 use run_make_support::symbols::any_symbol_contains;
@@ -36,5 +31,5 @@ fn main() {
         // otherwise, add them to the list of symbols to deny.
         panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]);
     }
-    assert!(!any_symbol_contains("main", &panic_syms));
+    assert!(!any_symbol_contains(bin_name("main"), &panic_syms));
 }
diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs
index 625ded70ad6..08e2b45a75f 100644
--- a/tests/run-make/textrel-on-minimal-lib/rmake.rs
+++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs
@@ -6,25 +6,23 @@
 // See https://github.com/rust-lang/rust/issues/68794
 
 //@ ignore-cross-compile
-//@ ignore-windows
-// Reason: There is no `bar.dll` produced by CC to run readobj on
 
 use run_make_support::{
-    cc, dynamic_lib_name, extra_c_flags, extra_cxx_flags, llvm_readobj, rustc, static_lib_name,
+    bin_name, cc, extra_c_flags, extra_cxx_flags, llvm_readobj, rustc, static_lib_name,
 };
 
 fn main() {
     rustc().input("foo.rs").run();
     cc().input("bar.c")
         .input(static_lib_name("foo"))
-        .out_exe(&dynamic_lib_name("bar"))
+        .out_exe(&bin_name("bar"))
         .arg("-fPIC")
         .arg("-shared")
         .args(extra_c_flags())
         .args(extra_cxx_flags())
         .run();
     llvm_readobj()
-        .input(dynamic_lib_name("bar"))
+        .input(bin_name("bar"))
         .arg("--dynamic")
         .run()
         .assert_stdout_not_contains("TEXTREL");
diff --git a/tests/ui/deprecation/deprecated-expr-precedence.rs b/tests/ui/deprecation/deprecated-expr-precedence.rs
new file mode 100644
index 00000000000..9636b46df20
--- /dev/null
+++ b/tests/ui/deprecation/deprecated-expr-precedence.rs
@@ -0,0 +1,8 @@
+//@ check-fail
+//@ compile-flags: --crate-type=lib
+
+// Regression test for issue 142649
+pub fn public() {
+    #[deprecated] 0
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/deprecation/deprecated-expr-precedence.stderr b/tests/ui/deprecation/deprecated-expr-precedence.stderr
new file mode 100644
index 00000000000..3275f2e790a
--- /dev/null
+++ b/tests/ui/deprecation/deprecated-expr-precedence.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/deprecated-expr-precedence.rs:6:19
+   |
+LL | pub fn public() {
+   |                - help: try adding a return type: `-> i32`
+LL |     #[deprecated] 0
+   |                   ^ expected `()`, found integer
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/unpretty/deprecated-attr.rs b/tests/ui/unpretty/deprecated-attr.rs
index 0c80203e965..e2ab5efb5d8 100644
--- a/tests/ui/unpretty/deprecated-attr.rs
+++ b/tests/ui/unpretty/deprecated-attr.rs
@@ -16,3 +16,8 @@ pub struct SinceAndNote;
 
 #[deprecated(note = "here's why this is deprecated", since = "1.2.3")]
 pub struct FlippedOrder;
+
+pub fn f() {
+    // Attribute is ignored here (with a warning), but still preserved in HIR
+    #[deprecated] 0
+}
diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout
index 97d863b2e94..a2b645d00d0 100644
--- a/tests/ui/unpretty/deprecated-attr.stdout
+++ b/tests/ui/unpretty/deprecated-attr.stdout
@@ -24,3 +24,12 @@ struct SinceAndNote;
 #[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"),
 note: "here's why this is deprecated"}}]
 struct FlippedOrder;
+
+fn f() {
+
+    // Attribute is ignored here (with a warning), but still preserved in HIR
+    #[attr = Deprecation {deprecation:
+    Deprecation {since:
+    Unspecified}}]
+    0
+}
diff --git a/tests/ui/unpretty/diagnostic-attr.stdout b/tests/ui/unpretty/diagnostic-attr.stdout
index 81d71b91d81..3b15a845d68 100644
--- a/tests/ui/unpretty/diagnostic-attr.stdout
+++ b/tests/ui/unpretty/diagnostic-attr.stdout
@@ -12,6 +12,4 @@ extern crate std;
 trait ImportantTrait<A> { }
 
 #[diagnostic::do_not_recommend]
-impl <T> ImportantTrait<T> for T where T: Clone
-    {#![diagnostic::do_not_recommend]
-}
+impl <T> ImportantTrait<T> for T where T: Clone { }
diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout
index 810db69bff1..ec9bda57331 100644
--- a/tests/ui/unpretty/exhaustive-asm.hir.stdout
+++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout
@@ -26,7 +26,7 @@ mod expressions {
 
 mod items {
     /// ItemKind::GlobalAsm
-    mod item_global_asm {/// ItemKind::GlobalAsm
+    mod item_global_asm {
         global_asm! (".globl my_asm_func");
     }
 }
diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout
index 5d6e3907d75..b15c02003a6 100644
--- a/tests/ui/unpretty/exhaustive.hir.stdout
+++ b/tests/ui/unpretty/exhaustive.hir.stdout
@@ -50,20 +50,14 @@ mod prelude {
     }
 }
 
-//! inner single-line doc comment
-/*!
+/// inner single-line doc comment
+/**
      * inner multi-line doc comment
      */
 #[doc = "inner doc attribute"]
 #[allow(dead_code, unused_variables)]
 #[no_std]
-mod attributes {//! inner single-line doc comment
-    /*!
-     * inner multi-line doc comment
-     */
-    #![doc = "inner doc attribute"]
-    #![allow(dead_code, unused_variables)]
-    #![no_std]
+mod attributes {
 
     /// outer single-line doc comment
     /**
@@ -413,25 +407,25 @@ mod expressions {
 }
 mod items {
     /// ItemKind::ExternCrate
-    mod item_extern_crate {/// ItemKind::ExternCrate
+    mod item_extern_crate {
         extern crate core;
         extern crate self as unpretty;
         extern crate core as _;
     }
     /// ItemKind::Use
-    mod item_use {/// ItemKind::Use
+    mod item_use {
         use ::{};
         use crate::expressions;
         use crate::items::item_use;
         use core::*;
     }
     /// ItemKind::Static
-    mod item_static {/// ItemKind::Static
+    mod item_static {
         static A: () = { };
         static mut B: () = { };
     }
     /// ItemKind::Const
-    mod item_const {/// ItemKind::Const
+    mod item_const {
         const A: () = { };
         trait TraitItems {
             const
@@ -445,7 +439,7 @@ mod items {
         }
     }
     /// ItemKind::Fn
-    mod item_fn {/// ItemKind::Fn
+    mod item_fn {
         const unsafe extern "C" fn f() { }
         async unsafe extern "C" fn g()
             ->
@@ -460,21 +454,19 @@ mod items {
         }
     }
     /// ItemKind::Mod
-    mod item_mod {/// ItemKind::Mod
-    }
+    mod item_mod { }
     /// ItemKind::ForeignMod
-    mod item_foreign_mod {/// ItemKind::ForeignMod
+    mod item_foreign_mod {
         extern "Rust" { }
         extern "C" { }
     }
     /// ItemKind::GlobalAsm: see exhaustive-asm.rs
     /// ItemKind::TyAlias
-    mod item_ty_alias {/// ItemKind::GlobalAsm: see exhaustive-asm.rs
-        /// ItemKind::TyAlias
+    mod item_ty_alias {
         type Type<'a> where T: 'a = T;
     }
     /// ItemKind::Enum
-    mod item_enum {/// ItemKind::Enum
+    mod item_enum {
         enum Void { }
         enum Empty {
             Unit,
@@ -490,7 +482,7 @@ mod items {
         }
     }
     /// ItemKind::Struct
-    mod item_struct {/// ItemKind::Struct
+    mod item_struct {
         struct Unit;
         struct Tuple();
         struct Newtype(Unit);
@@ -501,45 +493,40 @@ mod items {
         }
     }
     /// ItemKind::Union
-    mod item_union {/// ItemKind::Union
+    mod item_union {
         union Generic<'a, T> where T: 'a {
             t: T,
         }
     }
     /// ItemKind::Trait
-    mod item_trait {/// ItemKind::Trait
+    mod item_trait {
         auto unsafe trait Send { }
         trait Trait<'a>: Sized where Self: 'a { }
     }
     /// ItemKind::TraitAlias
-    mod item_trait_alias {/// ItemKind::TraitAlias
+    mod item_trait_alias {
         trait Trait<T> = Sized where for<'a> T: 'a;
     }
     /// ItemKind::Impl
-    mod item_impl {/// ItemKind::Impl
+    mod item_impl {
         impl () { }
         impl <T> () { }
         impl Default for () { }
         impl const <T> Default for () { }
     }
     /// ItemKind::MacCall
-    mod item_mac_call {/// ItemKind::MacCall
-    }
+    mod item_mac_call { }
     /// ItemKind::MacroDef
-    mod item_macro_def {/// ItemKind::MacroDef
+    mod item_macro_def {
         macro_rules! mac { () => {...}; }
         macro stringify { () => {} }
     }
     /// ItemKind::Delegation
-    /*! FIXME: todo */
-    mod item_delegation {/// ItemKind::Delegation
-        /*! FIXME: todo */
-    }
+    /** FIXME: todo */
+    mod item_delegation { }
     /// ItemKind::DelegationMac
-    /*! FIXME: todo */
-    mod item_delegation_mac {/// ItemKind::DelegationMac
-        /*! FIXME: todo */
-    }
+    /** FIXME: todo */
+    mod item_delegation_mac { }
 }
 mod patterns {
     /// PatKind::Missing
@@ -690,29 +677,29 @@ mod types {
     /// TyKind::Paren
     fn ty_paren() { let _: T; }
     /// TyKind::Typeof
-    /*! unused for now */
+    /** unused for now */
     fn ty_typeof() { }
     /// TyKind::Infer
     fn ty_infer() { let _: _; }
     /// TyKind::ImplicitSelf
-    /*! there is no syntax for this */
+    /** there is no syntax for this */
     fn ty_implicit_self() { }
     /// TyKind::MacCall
     #[expect(deprecated)]
     fn ty_mac_call() { let _: T; let _: T; let _: T; }
     /// TyKind::CVarArgs
-    /*! FIXME: todo */
+    /** FIXME: todo */
     fn ty_c_var_args() { }
     /// TyKind::Pat
     fn ty_pat() { let _: u32 is 1..=RangeMax; }
 }
 mod visibilities {
     /// VisibilityKind::Public
-    mod visibility_public {/// VisibilityKind::Public
+    mod visibility_public {
         struct Pub;
     }
     /// VisibilityKind::Restricted
-    mod visibility_restricted {/// VisibilityKind::Restricted
+    mod visibility_restricted {
         struct PubCrate;
         struct PubSelf;
         struct PubSuper;