diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 51dd0f81ed147..2e83bbf643fee 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -53,6 +53,13 @@ jobs:
     steps:
       - name: Checkout the source code
         uses: actions/checkout@v4
+      # Cache citool to make its build faster, as it's in the critical path.
+      # The rust-cache doesn't bleed into the main `job`, so it should not affect any other
+      # Rust compilation.
+      - name: Cache citool
+        uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
+        with:
+          workspaces: src/ci/citool
       - name: Calculate the CI job matrix
         env:
           COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b1d1c35e64a1d..5be740609c7cf 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1765,7 +1765,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         ident: Ident,
         is_anon_in_path: IsAnonInPath,
     ) -> &'hir hir::Lifetime {
-        debug_assert_ne!(ident.name, kw::Empty);
         let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
         let res = match res {
             LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param),
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 532c5092a4e94..d6a7bfc446a41 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1600,11 +1600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Ok(method)
             }
             Err(error) => {
-                if segment.ident.name == kw::Empty {
-                    span_bug!(rcvr.span, "empty method name")
-                } else {
-                    Err(self.report_method_error(expr.hir_id, rcvr_t, error, expected, false))
-                }
+                Err(self.report_method_error(expr.hir_id, rcvr_t, error, expected, false))
             }
         };
 
@@ -2941,9 +2937,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return Ty::new_error(self.tcx(), guar);
         }
 
-        let guar = if field.name == kw::Empty {
-            self.dcx().span_bug(field.span, "field name with no name")
-        } else if self.method_exists_for_diagnostic(
+        let guar = if self.method_exists_for_diagnostic(
             field,
             base_ty,
             expr.hir_id,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 91190a32ff548..87d92b3fbde8d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -27,9 +27,9 @@ use rustc_middle::ty::{
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::hygiene::DesugaringKind;
-use rustc_span::{Span, kw};
 use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_trait_selection::traits::{
     self, NormalizeExt, ObligationCauseCode, StructurallyNormalizeExt,
@@ -833,7 +833,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 let trait_missing_method =
                     matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait();
-                assert_ne!(item_name.name, kw::Empty);
                 self.report_method_error(
                     hir_id,
                     ty.normalized,
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index 76a1ff3cf3828..f0d24d27e85a3 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -290,7 +290,7 @@ pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) {
 
             // Try to remove the session directory we just allocated. We don't
             // know if there's any garbage in it from the failed copy action.
-            if let Err(err) = safe_remove_dir_all(&session_dir) {
+            if let Err(err) = std_fs::remove_dir_all(&session_dir) {
                 sess.dcx().emit_warn(errors::DeletePartial { path: &session_dir, err });
             }
 
@@ -324,7 +324,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) {
             incr_comp_session_dir.display()
         );
 
-        if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) {
+        if let Err(err) = std_fs::remove_dir_all(&*incr_comp_session_dir) {
             sess.dcx().emit_warn(errors::DeleteFull { path: &incr_comp_session_dir, err });
         }
 
@@ -715,7 +715,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
     for directory_name in session_directories {
         if !lock_file_to_session_dir.items().any(|(_, dir)| *dir == directory_name) {
             let path = crate_directory.join(directory_name);
-            if let Err(err) = safe_remove_dir_all(&path) {
+            if let Err(err) = std_fs::remove_dir_all(&path) {
                 sess.dcx().emit_warn(errors::InvalidGcFailed { path: &path, err });
             }
         }
@@ -821,7 +821,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
     all_except_most_recent(deletion_candidates).into_items().all(|(path, lock)| {
         debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
 
-        if let Err(err) = safe_remove_dir_all(&path) {
+        if let Err(err) = std_fs::remove_dir_all(&path) {
             sess.dcx().emit_warn(errors::FinalizedGcFailed { path: &path, err });
         } else {
             delete_session_dir_lock_file(sess, &lock_file_path(&path));
@@ -839,7 +839,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
 fn delete_old(sess: &Session, path: &Path) {
     debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
 
-    if let Err(err) = safe_remove_dir_all(path) {
+    if let Err(err) = std_fs::remove_dir_all(path) {
         sess.dcx().emit_warn(errors::SessionGcFailed { path, err });
     } else {
         delete_session_dir_lock_file(sess, &lock_file_path(path));
@@ -862,30 +862,8 @@ fn all_except_most_recent(
     }
 }
 
-/// Since paths of artifacts within session directories can get quite long, we
-/// need to support deleting files with very long paths. The regular
-/// WinApi functions only support paths up to 260 characters, however. In order
-/// to circumvent this limitation, we canonicalize the path of the directory
-/// before passing it to std::fs::remove_dir_all(). This will convert the path
-/// into the '\\?\' format, which supports much longer paths.
-fn safe_remove_dir_all(p: &Path) -> io::Result<()> {
-    let canonicalized = match try_canonicalize(p) {
-        Ok(canonicalized) => canonicalized,
-        Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
-        Err(err) => return Err(err),
-    };
-
-    std_fs::remove_dir_all(canonicalized)
-}
-
 fn safe_remove_file(p: &Path) -> io::Result<()> {
-    let canonicalized = match try_canonicalize(p) {
-        Ok(canonicalized) => canonicalized,
-        Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()),
-        Err(err) => return Err(err),
-    };
-
-    match std_fs::remove_file(canonicalized) {
+    match std_fs::remove_file(p) {
         Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()),
         result => result,
     }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 1dbb35f92c2cf..d1d0f7cacaee2 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -688,7 +688,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
                 let target_ty = self.monomorphize(target_ty);
                 let source_ty = self.monomorphize(source_ty);
                 let (source_ty, target_ty) =
-                    find_vtable_types_for_unsizing(self.tcx.at(span), source_ty, target_ty);
+                    find_tails_for_unsizing(self.tcx.at(span), source_ty, target_ty);
                 // This could also be a different Unsize instruction, like
                 // from a fixed sized array to a slice. But we are only
                 // interested in things that produce a vtable.
@@ -1037,36 +1037,35 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
 ///
 /// Finally, there is also the case of custom unsizing coercions, e.g., for
 /// smart pointers such as `Rc` and `Arc`.
-fn find_vtable_types_for_unsizing<'tcx>(
+fn find_tails_for_unsizing<'tcx>(
     tcx: TyCtxtAt<'tcx>,
     source_ty: Ty<'tcx>,
     target_ty: Ty<'tcx>,
 ) -> (Ty<'tcx>, Ty<'tcx>) {
-    let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
-        let typing_env = ty::TypingEnv::fully_monomorphized();
-        if tcx.type_has_metadata(inner_source, typing_env) {
-            (inner_source, inner_target)
-        } else {
-            tcx.struct_lockstep_tails_for_codegen(inner_source, inner_target, typing_env)
-        }
-    };
+    let typing_env = ty::TypingEnv::fully_monomorphized();
+    debug_assert!(!source_ty.has_param(), "{source_ty} should be fully monomorphic");
+    debug_assert!(!target_ty.has_param(), "{target_ty} should be fully monomorphic");
 
     match (source_ty.kind(), target_ty.kind()) {
-        (&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
-        | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
+        (
+            &ty::Ref(_, source_pointee, _),
+            &ty::Ref(_, target_pointee, _) | &ty::RawPtr(target_pointee, _),
+        )
+        | (&ty::RawPtr(source_pointee, _), &ty::RawPtr(target_pointee, _)) => {
+            tcx.struct_lockstep_tails_for_codegen(source_pointee, target_pointee, typing_env)
+        }
+
+        // `Box<T>` could go through the ADT code below, b/c it'll unpeel to `Unique<T>`,
+        // and eventually bottom out in a raw ref, but we can micro-optimize it here.
         (_, _)
             if let Some(source_boxed) = source_ty.boxed_ty()
                 && let Some(target_boxed) = target_ty.boxed_ty() =>
         {
-            ptr_vtable(source_boxed, target_boxed)
+            tcx.struct_lockstep_tails_for_codegen(source_boxed, target_boxed, typing_env)
         }
 
-        // T as dyn* Trait
-        (_, &ty::Dynamic(_, _, ty::DynStar)) => ptr_vtable(source_ty, target_ty),
-
         (&ty::Adt(source_adt_def, source_args), &ty::Adt(target_adt_def, target_args)) => {
             assert_eq!(source_adt_def, target_adt_def);
-
             let CustomCoerceUnsized::Struct(coerce_index) =
                 match crate::custom_coerce_unsize_info(tcx, source_ty, target_ty) {
                     Ok(ccu) => ccu,
@@ -1075,21 +1074,23 @@ fn find_vtable_types_for_unsizing<'tcx>(
                         return (e, e);
                     }
                 };
+            let coerce_field = &source_adt_def.non_enum_variant().fields[coerce_index];
+            // We're getting a possibly unnormalized type, so normalize it.
+            let source_field =
+                tcx.normalize_erasing_regions(typing_env, coerce_field.ty(*tcx, source_args));
+            let target_field =
+                tcx.normalize_erasing_regions(typing_env, coerce_field.ty(*tcx, target_args));
+            find_tails_for_unsizing(tcx, source_field, target_field)
+        }
 
-            let source_fields = &source_adt_def.non_enum_variant().fields;
-            let target_fields = &target_adt_def.non_enum_variant().fields;
-
-            assert!(
-                coerce_index.index() < source_fields.len()
-                    && source_fields.len() == target_fields.len()
-            );
+        // `T` as `dyn* Trait` unsizes *directly*.
+        //
+        // FIXME(dyn_star): This case is a bit awkward, b/c we're not really computing
+        // a tail here. We probably should handle this separately in the *caller* of
+        // this function, rather than returning something that is semantically different
+        // than what we return above.
+        (_, &ty::Dynamic(_, _, ty::DynStar)) => (source_ty, target_ty),
 
-            find_vtable_types_for_unsizing(
-                tcx,
-                source_fields[coerce_index].ty(*tcx, source_args),
-                target_fields[coerce_index].ty(*tcx, target_args),
-            )
-        }
         _ => bug!(
             "find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}",
             source_ty,
@@ -1308,7 +1309,7 @@ fn visit_mentioned_item<'tcx>(
         }
         MentionedItem::UnsizeCast { source_ty, target_ty } => {
             let (source_ty, target_ty) =
-                find_vtable_types_for_unsizing(tcx.at(span), source_ty, target_ty);
+                find_tails_for_unsizing(tcx.at(span), source_ty, target_ty);
             // This could also be a different Unsize instruction, like
             // from a fixed sized array to a slice. But we are only
             // interested in things that produce a vtable.
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 3f3b455f4db24..762e08b2be5f0 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -1012,7 +1012,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
                         // 2 segments, so the `resolve_path` above won't trigger it.
                         let mut full_path = import.module_path.clone();
-                        full_path.push(Segment::from_ident(Ident::empty()));
+                        full_path.push(Segment::from_ident(Ident::dummy()));
                         self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
                     }
 
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index a4e1266e76439..f310aa6550025 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -776,7 +776,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                                     self.push_disambiguator(
                                         disambiguated_field.disambiguator as u64,
                                     );
-                                    self.push_ident(field_name.unwrap_or(kw::Empty).as_str());
+                                    self.push_ident(field_name.unwrap().as_str());
 
                                     field.print(self)?;
                                 }
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index b6545eada86ae..5242261cf93f6 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2658,6 +2658,10 @@ impl<T, U> Chain<T, U> {
 
     /// Gets references to the underlying readers in this `Chain`.
     ///
+    /// Care should be taken to avoid modifying the internal I/O state of the
+    /// underlying readers as doing so may corrupt the internal state of this
+    /// `Chain`.
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -2915,6 +2919,10 @@ impl<T> Take<T> {
 
     /// Gets a reference to the underlying reader.
     ///
+    /// Care should be taken to avoid modifying the internal I/O state of the
+    /// underlying reader as doing so may corrupt the internal limit of this
+    /// `Take`.
+    ///
     /// # Examples
     ///
     /// ```no_run
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index fd4650ba28532..cb2bec5a9dfa6 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -23,8 +23,8 @@ runners:
     os: ubuntu-24.04-16core-64gb
     <<: *base-job
 
-  - &job-macos-xl
-    os: macos-13 # We use the standard runner for now
+  - &job-macos
+    os: macos-13
     <<: *base-job
 
   - &job-macos-m1
@@ -380,7 +380,7 @@ auto:
       NO_OVERFLOW_CHECKS: 1
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-macos-xl
+    <<: *job-macos
 
   - name: dist-apple-various
     env:
@@ -397,18 +397,18 @@ auto:
       NO_LLVM_ASSERTIONS: 1
       NO_DEBUG_ASSERTIONS: 1
       NO_OVERFLOW_CHECKS: 1
-    <<: *job-macos-xl
+    <<: *job-macos
 
   - name: x86_64-apple-1
     env:
       <<: *env-x86_64-apple-tests
-    <<: *job-macos-xl
+    <<: *job-macos
 
   - name: x86_64-apple-2
     env:
       SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc
       <<: *env-x86_64-apple-tests
-    <<: *job-macos-xl
+    <<: *job-macos
 
   - name: dist-aarch64-apple
     env:
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7786b216112bf..31aa84535cc4e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -517,7 +517,7 @@ impl Item {
                     Some(RenderedLink {
                         original_text: s.clone(),
                         new_text: link_text.clone(),
-                        tooltip: link_tooltip(*id, fragment, cx),
+                        tooltip: link_tooltip(*id, fragment, cx).to_string(),
                         href,
                     })
                 } else {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 41e9a5a665169..4998c671b61ed 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -11,6 +11,7 @@ use std::borrow::Cow;
 use std::cmp::Ordering;
 use std::fmt::{self, Display, Write};
 use std::iter::{self, once};
+use std::slice;
 
 use itertools::Either;
 use rustc_abi::ExternAbi;
@@ -650,33 +651,35 @@ pub(crate) fn href_relative_parts<'fqp>(
     }
 }
 
-pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Context<'_>) -> String {
-    let cache = cx.cache();
-    let Some((fqp, shortty)) = cache.paths.get(&did).or_else(|| cache.external_paths.get(&did))
-    else {
-        return String::new();
-    };
-    let mut buf = String::new();
-    let fqp = if *shortty == ItemType::Primitive {
-        // primitives are documented in a crate, but not actually part of it
-        &fqp[fqp.len() - 1..]
-    } else {
-        fqp
-    };
-    if let &Some(UrlFragment::Item(id)) = fragment {
-        write_str(&mut buf, format_args!("{} ", cx.tcx().def_descr(id)));
-        for component in fqp {
-            write_str(&mut buf, format_args!("{component}::"));
-        }
-        write_str(&mut buf, format_args!("{}", cx.tcx().item_name(id)));
-    } else if !fqp.is_empty() {
-        let mut fqp_it = fqp.iter();
-        write_str(&mut buf, format_args!("{shortty} {}", fqp_it.next().unwrap()));
-        for component in fqp_it {
-            write_str(&mut buf, format_args!("::{component}"));
+pub(crate) fn link_tooltip(
+    did: DefId,
+    fragment: &Option<UrlFragment>,
+    cx: &Context<'_>,
+) -> impl fmt::Display {
+    fmt::from_fn(move |f| {
+        let cache = cx.cache();
+        let Some((fqp, shortty)) = cache.paths.get(&did).or_else(|| cache.external_paths.get(&did))
+        else {
+            return Ok(());
+        };
+        let fqp = if *shortty == ItemType::Primitive {
+            // primitives are documented in a crate, but not actually part of it
+            slice::from_ref(fqp.last().unwrap())
+        } else {
+            fqp
+        };
+        if let &Some(UrlFragment::Item(id)) = fragment {
+            write!(f, "{} ", cx.tcx().def_descr(id))?;
+            for component in fqp {
+                write!(f, "{component}::")?;
+            }
+            write!(f, "{}", cx.tcx().item_name(id))?;
+        } else if !fqp.is_empty() {
+            write!(f, "{shortty} ")?;
+            fqp.iter().joined("::", f)?;
         }
-    }
-    buf
+        Ok(())
+    })
 }
 
 /// Used to render a [`clean::Path`].
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index e2d1f58a37ecb..596ac665fc313 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -650,15 +650,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
 
         bar.render_into(&mut sidebar).unwrap();
 
-        let v = layout::render(
-            &shared.layout,
-            &page,
-            sidebar,
-            BufDisplay(|buf: &mut String| {
-                all.print(buf);
-            }),
-            &shared.style_files,
-        );
+        let v = layout::render(&shared.layout, &page, sidebar, all.print(), &shared.style_files);
         shared.fs.write(final_file, v)?;
 
         // if to avoid writing help, settings files to doc root unless we're on the final invocation
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 21c823f49d15f..94171ad6de801 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -40,6 +40,7 @@ mod span_map;
 mod type_layout;
 mod write_shared;
 
+use std::borrow::Cow;
 use std::collections::VecDeque;
 use std::fmt::{self, Display as _, Write};
 use std::iter::Peekable;
@@ -47,6 +48,7 @@ use std::path::PathBuf;
 use std::{fs, str};
 
 use askama::Template;
+use itertools::Either;
 use rustc_attr_parsing::{
     ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
 };
@@ -98,6 +100,19 @@ enum AssocItemRender<'a> {
     DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
 }
 
+impl AssocItemRender<'_> {
+    fn render_mode(&self) -> RenderMode {
+        match self {
+            Self::All => RenderMode::Normal,
+            &Self::DerefFor { deref_mut_, .. } => RenderMode::ForDeref { mut_: deref_mut_ },
+        }
+    }
+
+    fn class(&self) -> Option<&'static str> {
+        if let Self::DerefFor { .. } = self { Some("impl-items") } else { None }
+    }
+}
+
 /// For different handling of associated items from the Deref target of a type rather than the type
 /// itself.
 #[derive(Copy, Clone, PartialEq)]
@@ -439,44 +454,49 @@ impl AllTypes {
         sections
     }
 
-    fn print(&self, f: &mut String) {
-        fn print_entries(f: &mut String, e: &FxIndexSet<ItemEntry>, kind: ItemSection) {
-            if !e.is_empty() {
+    fn print(&self) -> impl fmt::Display {
+        fn print_entries(e: &FxIndexSet<ItemEntry>, kind: ItemSection) -> impl fmt::Display {
+            fmt::from_fn(move |f| {
+                if e.is_empty() {
+                    return Ok(());
+                }
+
                 let mut e: Vec<&ItemEntry> = e.iter().collect();
                 e.sort();
-                write_str(
+                write!(
                     f,
-                    format_args!(
-                        "<h3 id=\"{id}\">{title}</h3><ul class=\"all-items\">",
-                        id = kind.id(),
-                        title = kind.name(),
-                    ),
-                );
+                    "<h3 id=\"{id}\">{title}</h3><ul class=\"all-items\">",
+                    id = kind.id(),
+                    title = kind.name(),
+                )?;
 
                 for s in e.iter() {
-                    write_str(f, format_args!("<li>{}</li>", s.print()));
+                    write!(f, "<li>{}</li>", s.print())?;
                 }
 
-                f.push_str("</ul>");
-            }
+                f.write_str("</ul>")
+            })
         }
 
-        f.push_str("<h1>List of all items</h1>");
-        // Note: print_entries does not escape the title, because we know the current set of titles
-        // doesn't require escaping.
-        print_entries(f, &self.structs, ItemSection::Structs);
-        print_entries(f, &self.enums, ItemSection::Enums);
-        print_entries(f, &self.unions, ItemSection::Unions);
-        print_entries(f, &self.primitives, ItemSection::PrimitiveTypes);
-        print_entries(f, &self.traits, ItemSection::Traits);
-        print_entries(f, &self.macros, ItemSection::Macros);
-        print_entries(f, &self.attribute_macros, ItemSection::AttributeMacros);
-        print_entries(f, &self.derive_macros, ItemSection::DeriveMacros);
-        print_entries(f, &self.functions, ItemSection::Functions);
-        print_entries(f, &self.type_aliases, ItemSection::TypeAliases);
-        print_entries(f, &self.trait_aliases, ItemSection::TraitAliases);
-        print_entries(f, &self.statics, ItemSection::Statics);
-        print_entries(f, &self.constants, ItemSection::Constants);
+        fmt::from_fn(|f| {
+            f.write_str("<h1>List of all items</h1>")?;
+            // Note: print_entries does not escape the title, because we know the current set of titles
+            // doesn't require escaping.
+            print_entries(&self.structs, ItemSection::Structs).fmt(f)?;
+            print_entries(&self.enums, ItemSection::Enums).fmt(f)?;
+            print_entries(&self.unions, ItemSection::Unions).fmt(f)?;
+            print_entries(&self.primitives, ItemSection::PrimitiveTypes).fmt(f)?;
+            print_entries(&self.traits, ItemSection::Traits).fmt(f)?;
+            print_entries(&self.macros, ItemSection::Macros).fmt(f)?;
+            print_entries(&self.attribute_macros, ItemSection::AttributeMacros).fmt(f)?;
+            print_entries(&self.derive_macros, ItemSection::DeriveMacros).fmt(f)?;
+            print_entries(&self.functions, ItemSection::Functions).fmt(f)?;
+            print_entries(&self.type_aliases, ItemSection::TypeAliases).fmt(f)?;
+            print_entries(&self.trait_aliases, ItemSection::TraitAliases).fmt(f)?;
+            print_entries(&self.statics, ItemSection::Statics).fmt(f)?;
+            print_entries(&self.constants, ItemSection::Constants).fmt(f)?;
+            Ok(())
+        })
     }
 }
 
@@ -1205,7 +1225,7 @@ impl<'a> AssocItemLink<'a> {
 }
 
 fn write_section_heading(
-    title: &str,
+    title: impl fmt::Display,
     id: &str,
     extra_class: Option<&str>,
     extra: impl fmt::Display,
@@ -1225,7 +1245,7 @@ fn write_section_heading(
     })
 }
 
-fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
+fn write_impl_section_heading(title: impl fmt::Display, id: &str) -> impl fmt::Display {
     write_section_heading(title, id, None, "")
 }
 
@@ -1302,20 +1322,17 @@ fn render_assoc_items_inner(
     let (mut non_trait, traits): (Vec<_>, _) =
         v.iter().partition(|i| i.inner_impl().trait_.is_none());
     if !non_trait.is_empty() {
-        let mut close_tags = <Vec<&str>>::with_capacity(1);
-        let mut tmp_buf = String::new();
-        let (render_mode, id, class_html) = match what {
-            AssocItemRender::All => {
-                write_str(
-                    &mut tmp_buf,
-                    format_args!(
-                        "{}",
-                        write_impl_section_heading("Implementations", "implementations")
-                    ),
-                );
-                (RenderMode::Normal, "implementations-list".to_owned(), "")
-            }
-            AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
+        let render_mode = what.render_mode();
+        let class_html = what
+            .class()
+            .map(|class| fmt::from_fn(move |f| write!(f, r#" class="{class}""#)))
+            .maybe_display();
+        let (section_heading, id) = match what {
+            AssocItemRender::All => (
+                Either::Left(write_impl_section_heading("Implementations", "implementations")),
+                Cow::Borrowed("implementations-list"),
+            ),
+            AssocItemRender::DerefFor { trait_, type_, .. } => {
                 let id =
                     cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
                 // the `impls.get` above only looks at the outermost type,
@@ -1329,25 +1346,27 @@ fn render_assoc_items_inner(
                     type_.is_doc_subtype_of(&impl_.inner_impl().for_, &cx.shared.cache)
                 });
                 let derived_id = cx.derive_id(&id);
-                close_tags.push("</details>");
-                write_str(
-                    &mut tmp_buf,
-                    format_args!(
-                        "<details class=\"toggle big-toggle\" open><summary>{}</summary>",
-                        write_impl_section_heading(
-                            &format!(
-                                "<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
-                                trait_ = trait_.print(cx),
-                                type_ = type_.print(cx),
-                            ),
-                            &id,
-                        )
-                    ),
-                );
                 if let Some(def_id) = type_.def_id(cx.cache()) {
-                    cx.deref_id_map.borrow_mut().insert(def_id, id);
+                    cx.deref_id_map.borrow_mut().insert(def_id, id.clone());
                 }
-                (RenderMode::ForDeref { mut_: deref_mut_ }, derived_id, r#" class="impl-items""#)
+                (
+                    Either::Right(fmt::from_fn(move |f| {
+                        write!(
+                            f,
+                            "<details class=\"toggle big-toggle\" open><summary>{}</summary>",
+                            write_impl_section_heading(
+                                fmt::from_fn(|f| write!(
+                                    f,
+                                    "<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
+                                    trait_ = trait_.print(cx),
+                                    type_ = type_.print(cx),
+                                )),
+                                &id,
+                            )
+                        )
+                    })),
+                    Cow::Owned(derived_id),
+                )
             }
         };
         let mut impls_buf = String::new();
@@ -1375,10 +1394,14 @@ fn render_assoc_items_inner(
             );
         }
         if !impls_buf.is_empty() {
-            write!(w, "{tmp_buf}<div id=\"{id}\"{class_html}>{impls_buf}</div>").unwrap();
-            for tag in close_tags.into_iter().rev() {
-                w.write_str(tag).unwrap();
-            }
+            write!(
+                w,
+                "{section_heading}<div id=\"{id}\"{class_html}>{impls_buf}</div>{}",
+                matches!(what, AssocItemRender::DerefFor { .. })
+                    .then_some("</details>")
+                    .maybe_display(),
+            )
+            .unwrap();
         }
     }
 
@@ -1639,8 +1662,8 @@ fn render_impl(
         // `containing_item` is used for rendering stability info. If the parent is a trait impl,
         // `containing_item` will the grandparent, since trait impls can't have stability attached.
         fn doc_impl_item(
-            boring: &mut String,
-            interesting: &mut String,
+            boring: impl fmt::Write,
+            interesting: impl fmt::Write,
             cx: &Context<'_>,
             item: &clean::Item,
             parent: &clean::Item,
@@ -1649,7 +1672,7 @@ fn render_impl(
             is_default_item: bool,
             trait_: Option<&clean::Trait>,
             rendering_params: ImplRenderingParameters,
-        ) {
+        ) -> fmt::Result {
             let item_type = item.type_();
             let name = item.name.as_ref().unwrap();
 
@@ -1724,15 +1747,16 @@ fn render_impl(
                     );
                 }
             }
-            let w = if short_documented && trait_.is_some() { interesting } else { boring };
+            let mut w = if short_documented && trait_.is_some() {
+                Either::Left(interesting)
+            } else {
+                Either::Right(boring)
+            };
 
             let toggled = !doc_buffer.is_empty();
             if toggled {
                 let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
-                write_str(
-                    w,
-                    format_args!("<details class=\"toggle{method_toggle_class}\" open><summary>"),
-                );
+                write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>")?;
             }
             match &item.kind {
                 clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
@@ -1747,172 +1771,151 @@ fn render_impl(
                                     .find(|item| item.name.map(|n| n == *name).unwrap_or(false))
                             })
                             .map(|item| format!("{}.{name}", item.type_()));
-                        write_str(
+                        write!(
                             w,
-                            format_args!(
-                                "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
+                            "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
                                 {}",
-                                render_rightside(cx, item, render_mode)
-                            ),
-                        );
+                            render_rightside(cx, item, render_mode)
+                        )?;
                         if trait_.is_some() {
                             // Anchors are only used on trait impls.
-                            write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
+                            write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                         }
-                        write_str(
+                        write!(
                             w,
-                            format_args!(
-                                "<h4 class=\"code-header\">{}</h4></section>",
-                                render_assoc_item(
-                                    item,
-                                    link.anchor(source_id.as_ref().unwrap_or(&id)),
-                                    ItemType::Impl,
-                                    cx,
-                                    render_mode,
-                                ),
+                            "<h4 class=\"code-header\">{}</h4></section>",
+                            render_assoc_item(
+                                item,
+                                link.anchor(source_id.as_ref().unwrap_or(&id)),
+                                ItemType::Impl,
+                                cx,
+                                render_mode,
                             ),
-                        );
+                        )?;
                     }
                 }
                 clean::RequiredAssocConstItem(generics, ty) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
+                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
                             {}",
-                            render_rightside(cx, item, render_mode)
-                        ),
-                    );
+                        render_rightside(cx, item, render_mode)
+                    )?;
                     if trait_.is_some() {
                         // Anchors are only used on trait impls.
-                        write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
+                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                     }
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<h4 class=\"code-header\">{}</h4></section>",
-                            assoc_const(
-                                item,
-                                generics,
-                                ty,
-                                AssocConstValue::None,
-                                link.anchor(if trait_.is_some() { &source_id } else { &id }),
-                                0,
-                                cx,
-                            )
+                        "<h4 class=\"code-header\">{}</h4></section>",
+                        assoc_const(
+                            item,
+                            generics,
+                            ty,
+                            AssocConstValue::None,
+                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
+                            0,
+                            cx,
                         ),
-                    );
+                    )?;
                 }
                 clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
+                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
                             {}",
-                            render_rightside(cx, item, render_mode)
-                        ),
-                    );
+                        render_rightside(cx, item, render_mode),
+                    )?;
                     if trait_.is_some() {
                         // Anchors are only used on trait impls.
-                        write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
+                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                     }
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<h4 class=\"code-header\">{}</h4></section>",
-                            assoc_const(
-                                item,
-                                &ci.generics,
-                                &ci.type_,
-                                match item.kind {
-                                    clean::ProvidedAssocConstItem(_) =>
-                                        AssocConstValue::TraitDefault(&ci.kind),
-                                    clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
-                                    _ => unreachable!(),
-                                },
-                                link.anchor(if trait_.is_some() { &source_id } else { &id }),
-                                0,
-                                cx,
-                            )
+                        "<h4 class=\"code-header\">{}</h4></section>",
+                        assoc_const(
+                            item,
+                            &ci.generics,
+                            &ci.type_,
+                            match item.kind {
+                                clean::ProvidedAssocConstItem(_) =>
+                                    AssocConstValue::TraitDefault(&ci.kind),
+                                clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
+                                _ => unreachable!(),
+                            },
+                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
+                            0,
+                            cx,
                         ),
-                    );
+                    )?;
                 }
                 clean::RequiredAssocTypeItem(generics, bounds) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
+                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
                             {}",
-                            render_rightside(cx, item, render_mode)
-                        ),
-                    );
+                        render_rightside(cx, item, render_mode),
+                    )?;
                     if trait_.is_some() {
                         // Anchors are only used on trait impls.
-                        write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
+                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                     }
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<h4 class=\"code-header\">{}</h4></section>",
-                            assoc_type(
-                                item,
-                                generics,
-                                bounds,
-                                None,
-                                link.anchor(if trait_.is_some() { &source_id } else { &id }),
-                                0,
-                                cx,
-                            )
+                        "<h4 class=\"code-header\">{}</h4></section>",
+                        assoc_type(
+                            item,
+                            generics,
+                            bounds,
+                            None,
+                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
+                            0,
+                            cx,
                         ),
-                    );
+                    )?;
                 }
                 clean::AssocTypeItem(tydef, _bounds) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
+                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
                             {}",
-                            render_rightside(cx, item, render_mode)
-                        ),
-                    );
+                        render_rightside(cx, item, render_mode),
+                    )?;
                     if trait_.is_some() {
                         // Anchors are only used on trait impls.
-                        write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
+                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                     }
-                    write_str(
+                    write!(
                         w,
-                        format_args!(
-                            "<h4 class=\"code-header\">{}</h4></section>",
-                            assoc_type(
-                                item,
-                                &tydef.generics,
-                                &[], // intentionally leaving out bounds
-                                Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
-                                link.anchor(if trait_.is_some() { &source_id } else { &id }),
-                                0,
-                                cx,
-                            )
+                        "<h4 class=\"code-header\">{}</h4></section>",
+                        assoc_type(
+                            item,
+                            &tydef.generics,
+                            &[], // intentionally leaving out bounds
+                            Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
+                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
+                            0,
+                            cx,
                         ),
-                    );
+                    )?;
                 }
-                clean::StrippedItem(..) => return,
+                clean::StrippedItem(..) => return Ok(()),
                 _ => panic!("can't make docs for trait item with name {:?}", item.name),
             }
 
-            w.push_str(&info_buffer);
+            w.write_str(&info_buffer)?;
             if toggled {
-                w.push_str("</summary>");
-                w.push_str(&doc_buffer);
-                w.push_str("</details>");
+                write!(w, "</summary>{doc_buffer}</details>")?;
             }
+            Ok(())
         }
 
         let mut impl_items = String::new();
@@ -1955,7 +1958,7 @@ fn render_impl(
                             false,
                             trait_,
                             rendering_params,
-                        );
+                        )?;
                     }
                     _ => {}
                 }
@@ -1973,7 +1976,7 @@ fn render_impl(
                     false,
                     trait_,
                     rendering_params,
-                );
+                )?;
             }
             for method in methods {
                 doc_impl_item(
@@ -1987,20 +1990,20 @@ fn render_impl(
                     false,
                     trait_,
                     rendering_params,
-                );
+                )?;
             }
         }
 
         fn render_default_items(
-            boring: &mut String,
-            interesting: &mut String,
+            mut boring: impl fmt::Write,
+            mut interesting: impl fmt::Write,
             cx: &Context<'_>,
             t: &clean::Trait,
             i: &clean::Impl,
             parent: &clean::Item,
             render_mode: RenderMode,
             rendering_params: ImplRenderingParameters,
-        ) {
+        ) -> fmt::Result {
             for trait_item in &t.items {
                 // Skip over any default trait items that are impossible to reference
                 // (e.g. if it has a `Self: Sized` bound on an unsized type).
@@ -2020,8 +2023,8 @@ fn render_impl(
                 let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);
 
                 doc_impl_item(
-                    boring,
-                    interesting,
+                    &mut boring,
+                    &mut interesting,
                     cx,
                     trait_item,
                     parent,
@@ -2030,8 +2033,9 @@ fn render_impl(
                     true,
                     Some(t),
                     rendering_params,
-                );
+                )?;
             }
+            Ok(())
         }
 
         // If we've implemented a trait, then also emit documentation for all
@@ -2051,7 +2055,7 @@ fn render_impl(
                     &i.impl_item,
                     render_mode,
                     rendering_params,
-                );
+                )?;
             }
         }
         if render_mode == RenderMode::Normal {
diff --git a/src/librustdoc/html/render/tests.rs b/src/librustdoc/html/render/tests.rs
index 657cd3c82aae3..327a30887b1db 100644
--- a/src/librustdoc/html/render/tests.rs
+++ b/src/librustdoc/html/render/tests.rs
@@ -47,8 +47,7 @@ fn test_all_types_prints_header_once() {
     // Regression test for #82477
     let all_types = AllTypes::new();
 
-    let mut buffer = String::new();
-    all_types.print(&mut buffer);
+    let buffer = all_types.print().to_string();
 
     assert_eq!(1, buffer.matches("List of all items").count());
 }
diff --git a/tests/crashes/74451.rs b/tests/crashes/74451.rs
deleted file mode 100644
index 8f93699467896..0000000000000
--- a/tests/crashes/74451.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//@ known-bug: #74451
-//@ compile-flags: -Copt-level=0
-
-#![feature(specialization)]
-#![feature(unsize, coerce_unsized)]
-#![allow(incomplete_features)]
-#![crate_type = "lib"]
-
-use std::ops::CoerceUnsized;
-
-pub struct SmartassPtr<A: Smartass+?Sized>(A::Data);
-
-pub trait Smartass {
-    type Data;
-    type Data2: CoerceUnsized<*const [u8]>;
-}
-
-pub trait MaybeObjectSafe {}
-
-impl MaybeObjectSafe for () {}
-
-impl<T> Smartass for T {
-    type Data = <Self as Smartass>::Data2;
-    default type Data2 = *const [u8; 0];
-}
-
-impl Smartass for () {
-    type Data2 = *const [u8; 1];
-}
-
-impl Smartass for dyn MaybeObjectSafe {
-    type Data = *const [u8];
-    type Data2 = *const [u8; 0];
-}
-
-impl<U: Smartass+?Sized, T: Smartass+?Sized> CoerceUnsized<SmartassPtr<T>> for SmartassPtr<U>
-    where <U as Smartass>::Data: std::ops::CoerceUnsized<<T as Smartass>::Data>
-{}
-
-pub fn conv(s: SmartassPtr<()>) -> SmartassPtr<dyn MaybeObjectSafe> {
-    s // This shouldn't coerce
-}
diff --git a/tests/ui/coercion/codegen-smart-pointer-with-alias.rs b/tests/ui/coercion/codegen-smart-pointer-with-alias.rs
new file mode 100644
index 0000000000000..a68952bb70aa2
--- /dev/null
+++ b/tests/ui/coercion/codegen-smart-pointer-with-alias.rs
@@ -0,0 +1,32 @@
+//@ build-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/139812>.
+
+// Make sure that the unsize coercion we collect in mono for `Signal<i32> -> Signal<dyn Any>`
+// doesn't choke on the fact that the inner unsized field of `Signal<T>` is a (trivial) alias.
+// This exercises a normalize call that is necessary since we're getting a type from the type
+// system, which isn't guaranteed to be normalized after substitution.
+
+#![feature(coerce_unsized)]
+
+use std::ops::CoerceUnsized;
+
+trait Mirror {
+    type Assoc: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+    type Assoc = T;
+}
+
+trait Any {}
+impl<T> Any for T {}
+
+struct Signal<'a, T: ?Sized>(<&'a T as Mirror>::Assoc);
+
+// This `CoerceUnsized` impl isn't special; it's a bit more restricted than we'd see in the wild,
+// but this ICE also reproduces if we were to make it general over `Signal<T> -> Signal<U>`.
+impl<'a> CoerceUnsized<Signal<'a, dyn Any>> for Signal<'a, i32> {}
+
+fn main() {
+    Signal(&1i32) as Signal<dyn Any>;
+}