about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-25 19:53:57 +0000
committerbors <bors@rust-lang.org>2025-03-25 19:53:57 +0000
commit43f0014ef0f242418674f49052ed39b70f73bc1c (patch)
tree926b46f8a13419513fdceed630a14fe9cf89e089
parent40507bded561ca6d28f3e187aed8317bb81ce9e2 (diff)
parent1107fc7ad22b7a37b6235ca0356390a2fea8be45 (diff)
downloadrust-43f0014ef0f242418674f49052ed39b70f73bc1c.tar.gz
rust-43f0014ef0f242418674f49052ed39b70f73bc1c.zip
Auto merge of #138933 - matthiaskrgr:rollup-sjtqkoq, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #135745 (Recognise new IPv6 non-global range from IETF RFC 9602)
 - #137247 (cg_llvm: Reduce the visibility of types, modules and using declarations in `rustc_codegen_llvm`.)
 - #138317 (privacy: Visit types and traits in impls in type privacy lints)
 - #138581 (Abort in deadlock handler if we fail to get a query map)
 - #138776 (coverage: Separate span-extraction from unexpansion)
 - #138886 (Fix autofix for `self` and `self as …` in `unused_imports` lint)
 - #138924 (Reduce `kw::Empty` usage, part 3)
 - #138929 (Visitors track whether an assoc item is in a trait impl or an inherent impl)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/visit.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs16
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs62
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs6
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs13
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs20
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs44
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs182
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs20
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0789.md2
-rw-r--r--compiler/rustc_expand/src/base.rs15
-rw-r--r--compiler/rustc_expand/src/expand.rs101
-rw-r--r--compiler/rustc_expand/src/placeholders.rs14
-rw-r--r--compiler/rustc_interface/src/util.rs15
-rw-r--r--compiler/rustc_lint/src/early.rs4
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs13
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs21
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs45
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs105
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_passes/src/errors.rs20
-rw-r--r--compiler/rustc_passes/src/lang_items.rs14
-rw-r--r--compiler/rustc_privacy/src/lib.rs40
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs24
-rw-r--r--compiler/rustc_query_system/src/query/job.rs7
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs2
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs7
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs25
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs3
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs4
-rw-r--r--compiler/rustc_resolve/src/lib.rs20
-rw-r--r--compiler/rustc_resolve/src/macros.rs13
-rw-r--r--library/core/src/net/ip_addr.rs2
-rw-r--r--library/coretests/tests/net/ip_addr.rs2
-rw-r--r--src/tools/rustfmt/src/visitor.rs3
-rw-r--r--tests/ui/attributes/crate-name-empty.rs5
-rw-r--r--tests/ui/attributes/crate-name-empty.stderr8
-rw-r--r--tests/ui/lint/unused/lint-unused-imports-self-single.fixed29
-rw-r--r--tests/ui/lint/unused/lint-unused-imports-self-single.rs30
-rw-r--r--tests/ui/lint/unused/lint-unused-imports-self-single.stderr44
-rw-r--r--tests/ui/privacy/pub-priv-dep/pub-priv1.rs7
-rw-r--r--tests/ui/privacy/pub-priv-dep/pub-priv1.stderr22
51 files changed, 683 insertions, 395 deletions
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 4edd0864300..604555e2df7 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1318,7 +1318,9 @@ impl WalkItemKind for ItemKind {
                 visit_polarity(vis, polarity);
                 visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
                 vis.visit_ty(self_ty);
-                items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Impl));
+                items.flat_map_in_place(|item| {
+                    vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
+                });
             }
             ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
                 visit_safety(vis, safety);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index ce8d6df75af..9f6a5324808 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -23,7 +23,7 @@ use crate::ptr::P;
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub enum AssocCtxt {
     Trait,
-    Impl,
+    Impl { of_trait: bool },
 }
 
 #[derive(Copy, Clone, Debug, PartialEq)]
@@ -422,7 +422,12 @@ impl WalkItemKind for ItemKind {
                 try_visit!(visitor.visit_generics(generics));
                 visit_opt!(visitor, visit_trait_ref, of_trait);
                 try_visit!(visitor.visit_ty(self_ty));
-                walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
+                walk_list!(
+                    visitor,
+                    visit_assoc_item,
+                    items,
+                    AssocCtxt::Impl { of_trait: of_trait.is_some() }
+                );
             }
             ItemKind::Struct(struct_definition, generics)
             | ItemKind::Union(struct_definition, generics) => {
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index efc1fa05c5f..f7640c602d6 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -61,8 +61,14 @@ pub(crate) struct DelegationResults<'hir> {
 
 impl<'hir> LoweringContext<'_, 'hir> {
     /// Defines whether the delegatee is an associated function whose first parameter is `self`.
-    pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool {
-        let sig_id = self.get_delegation_sig_id(item_id, path_id, span);
+    pub(crate) fn delegatee_is_method(
+        &self,
+        item_id: NodeId,
+        path_id: NodeId,
+        span: Span,
+        is_in_trait_impl: bool,
+    ) -> bool {
+        let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl);
         let Ok(sig_id) = sig_id else {
             return false;
         };
@@ -88,9 +94,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         &mut self,
         delegation: &Delegation,
         item_id: NodeId,
+        is_in_trait_impl: bool,
     ) -> DelegationResults<'hir> {
         let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
-        let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);
+        let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
         match sig_id {
             Ok(sig_id) => {
                 let (param_count, c_variadic) = self.param_count(sig_id);
@@ -110,8 +117,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         item_id: NodeId,
         path_id: NodeId,
         span: Span,
+        is_in_trait_impl: bool,
     ) -> Result<DefId, ErrorGuaranteed> {
-        let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
+        let sig_id = if is_in_trait_impl { item_id } else { path_id };
         self.get_resolution_id(sig_id, span)
     }
 
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 219bf62c916..54f27eab5bc 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_hir::{self as hir, HirId, PredicateOrigin};
 use rustc_index::{IndexSlice, IndexVec};
-use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
@@ -104,10 +103,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
     }
 
     fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
-        let def_id = self.resolver.node_id_to_def_id[&item.id];
-        let parent_id = self.tcx.local_parent(def_id);
-        let parent_hir = self.lower_node(parent_id).unwrap();
-        self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt, parent_hir))
+        self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
     }
 
     fn lower_foreign_item(&mut self, item: &ForeignItem) {
@@ -405,10 +401,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         (trait_ref, lowered_ty)
                     });
 
-                self.is_in_trait_impl = trait_ref.is_some();
-                let new_impl_items = self
-                    .arena
-                    .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
+                let new_impl_items = self.arena.alloc_from_iter(
+                    impl_items
+                        .iter()
+                        .map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
+                );
 
                 // `defaultness.has_value()` is never called for an `impl`, always `true` in order
                 // to not cause an assertion failure inside the `lower_defaultness` function.
@@ -485,7 +482,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             ItemKind::Delegation(box delegation) => {
                 debug_assert_ne!(ident.name, kw::Empty);
                 let ident = self.lower_ident(ident);
-                let delegation_results = self.lower_delegation(delegation, id);
+                let delegation_results = self.lower_delegation(delegation, id, false);
                 hir::ItemKind::Fn {
                     ident,
                     sig: delegation_results.sig,
@@ -628,29 +625,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    fn lower_assoc_item(
-        &mut self,
-        item: &AssocItem,
-        ctxt: AssocCtxt,
-        parent_hir: &'hir hir::OwnerInfo<'hir>,
-    ) -> hir::OwnerNode<'hir> {
-        let parent_item = parent_hir.node().expect_item();
-        match parent_item.kind {
-            hir::ItemKind::Impl(impl_) => {
-                self.is_in_trait_impl = impl_.of_trait.is_some();
-            }
-            hir::ItemKind::Trait(..) => {}
-            kind => {
-                span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
-            }
-        }
-
+    fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
         // Evaluate with the lifetimes in `params` in-scope.
         // This is used to track which lifetimes have already been defined,
         // and which need to be replicated when lowering an async fn.
         match ctxt {
             AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
-            AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
+            AssocCtxt::Impl { of_trait } => {
+                hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
+            }
         }
     }
 
@@ -891,7 +874,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 (generics, kind, ty.is_some())
             }
             AssocItemKind::Delegation(box delegation) => {
-                let delegation_results = self.lower_delegation(delegation, i.id);
+                let delegation_results = self.lower_delegation(delegation, i.id, false);
                 let item_kind = hir::TraitItemKind::Fn(
                     delegation_results.sig,
                     hir::TraitFn::Provided(delegation_results.body_id),
@@ -922,7 +905,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
             }
             AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
-                has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
+                has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
             },
             AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
                 panic!("macros should have been expanded by now")
@@ -942,7 +925,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.expr(span, hir::ExprKind::Err(guar))
     }
 
-    fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
+    fn lower_impl_item(
+        &mut self,
+        i: &AssocItem,
+        is_in_trait_impl: bool,
+    ) -> &'hir hir::ImplItem<'hir> {
         debug_assert_ne!(i.ident.name, kw::Empty);
         // Since `default impl` is not yet implemented, this is always true in impls.
         let has_value = true;
@@ -978,7 +965,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     sig,
                     i.id,
-                    if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
+                    if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
                     sig.header.coroutine_kind,
                     attrs,
                 );
@@ -1018,7 +1005,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 )
             }
             AssocItemKind::Delegation(box delegation) => {
-                let delegation_results = self.lower_delegation(delegation, i.id);
+                let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
                 (
                     delegation_results.generics,
                     hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
@@ -1041,7 +1028,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.arena.alloc(item)
     }
 
-    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
+    fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
         hir::ImplItemRef {
             id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
             ident: self.lower_ident(i.ident),
@@ -1053,7 +1040,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
                 }
                 AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
-                    has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
+                    has_self: self.delegatee_is_method(
+                        i.id,
+                        delegation.id,
+                        i.span,
+                        is_in_trait_impl,
+                    ),
                 },
                 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
                     panic!("macros should have been expanded by now")
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 6c380d77b49..1463dcc2b69 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -121,7 +121,6 @@ struct LoweringContext<'a, 'hir> {
     catch_scope: Option<HirId>,
     loop_scope: Option<HirId>,
     is_in_loop_condition: bool,
-    is_in_trait_impl: bool,
     is_in_dyn_type: bool,
 
     current_hir_id_owner: hir::OwnerId,
@@ -173,7 +172,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             catch_scope: None,
             loop_scope: None,
             is_in_loop_condition: false,
-            is_in_trait_impl: false,
             is_in_dyn_type: false,
             coroutine_kind: None,
             task_context: None,
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 75839e86b8d..a1487ca74be 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -860,7 +860,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     this.visit_trait_ref(t);
                     this.visit_ty(self_ty);
 
-                    walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
+                    walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: true });
                 });
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
@@ -913,7 +913,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         |this| this.visit_generics(generics),
                     );
                     this.visit_ty(self_ty);
-                    walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
+                    walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: false });
                 });
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
@@ -1414,7 +1414,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             self.check_defaultness(item.span, item.kind.defaultness());
         }
 
-        if ctxt == AssocCtxt::Impl {
+        if let AssocCtxt::Impl { .. } = ctxt {
             match &item.kind {
                 AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
                     self.dcx().emit_err(errors::AssocConstWithoutBody {
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index 6d76456e83c..bdad6b50186 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -5,7 +5,7 @@ use rustc_attr_data_structures::{
     StableSince, UnstableReason, VERSION_PLACEHOLDER,
 };
 use rustc_errors::ErrorGuaranteed;
-use rustc_span::{Span, Symbol, kw, sym};
+use rustc_span::{Span, Symbol, sym};
 
 use super::util::parse_version;
 use super::{AcceptMapping, AttributeParser, SingleAttributeParser};
@@ -61,11 +61,7 @@ impl AttributeParser for StabilityParser {
         }),
         (&[sym::rustc_allowed_through_unstable_modules], |this, cx, args| {
             reject_outside_std!(cx);
-            this.allowed_through_unstable_modules =
-                Some(match args.name_value().and_then(|i| i.value_as_str()) {
-                    Some(msg) => msg,
-                    None => kw::Empty,
-                });
+            this.allowed_through_unstable_modules = args.name_value().and_then(|i| i.value_as_str())
         }),
     ];
 
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 6591ed151cf..5cd653c7945 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -157,7 +157,7 @@ mod llvm_enzyme {
                 };
                 (sig.clone(), false)
             }
-            Annotatable::AssocItem(assoc_item, _) => {
+            Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
                 let sig = match &assoc_item.kind {
                     ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
                     _ => {
@@ -296,7 +296,7 @@ mod llvm_enzyme {
                 }
                 Annotatable::Item(iitem.clone())
             }
-            Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => {
+            Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => {
                 if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
                     assoc_item.attrs.push(attr);
                 }
@@ -327,7 +327,7 @@ mod llvm_enzyme {
                 kind: assoc_item,
                 tokens: None,
             });
-            Annotatable::AssocItem(d_fn, Impl)
+            Annotatable::AssocItem(d_fn, Impl { of_trait: false })
         } else {
             let mut d_fn =
                 ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 5788966b6e7..b3ba9073118 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -121,18 +121,11 @@ impl CfgEval<'_> {
                     let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
                     Annotatable::Item(self.flat_map_item(item).pop().unwrap())
                 }
-                Annotatable::AssocItem(_, AssocCtxt::Trait) => {
+                Annotatable::AssocItem(_, ctxt) => {
                     let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
                     Annotatable::AssocItem(
-                        self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(),
-                        AssocCtxt::Trait,
-                    )
-                }
-                Annotatable::AssocItem(_, AssocCtxt::Impl) => {
-                    let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap();
-                    Annotatable::AssocItem(
-                        self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(),
-                        AssocCtxt::Impl,
+                        self.flat_map_assoc_item(item, ctxt).pop().unwrap(),
+                        ctxt,
                     )
                 }
                 Annotatable::ForeignItem(_) => {
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index 2653a9f48b9..e259f5b3955 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -103,7 +103,7 @@ impl MultiItemModifier for Expander {
 fn dummy_annotatable() -> Annotatable {
     Annotatable::GenericParam(ast::GenericParam {
         id: ast::DUMMY_NODE_ID,
-        ident: Ident::empty(),
+        ident: Ident::dummy(),
         attrs: Default::default(),
         bounds: Default::default(),
         is_placeholder: false,
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 668795191a2..f083cfbd7d3 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -728,7 +728,7 @@ impl ThinBuffer {
         }
     }
 
-    pub unsafe fn from_raw_ptr(ptr: *mut llvm::ThinLTOBuffer) -> ThinBuffer {
+    pub(crate) unsafe fn from_raw_ptr(ptr: *mut llvm::ThinLTOBuffer) -> ThinBuffer {
         let mut ptr = NonNull::new(ptr).unwrap();
         ThinBuffer(unsafe { ptr.as_mut() })
     }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index f622646a5d9..425381b0ffa 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -29,7 +29,7 @@ use back::owned_target_machine::OwnedTargetMachine;
 use back::write::{create_informational_target_machine, create_target_machine};
 use context::SimpleCx;
 use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig};
-pub(crate) use llvm_util::target_features_cfg;
+use llvm_util::target_features_cfg;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
@@ -71,9 +71,7 @@ mod debuginfo;
 mod declare;
 mod errors;
 mod intrinsic;
-// FIXME(Zalathar): Fix all the unreachable-pub warnings that would occur if
-// this isn't pub, then make it not pub.
-pub mod llvm;
+mod llvm;
 mod llvm_util;
 mod mono_item;
 mod type_;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
index 63b2b15c514..51bcc4d123d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs
@@ -5,17 +5,17 @@ use std::{slice, str};
 
 use rustc_fs_util::path_to_c_string;
 
-pub struct ArchiveRO {
+pub(crate) struct ArchiveRO {
     pub raw: &'static mut super::Archive,
 }
 
 unsafe impl Send for ArchiveRO {}
 
-pub struct Iter<'a> {
+pub(crate) struct Iter<'a> {
     raw: &'a mut super::ArchiveIterator<'a>,
 }
 
-pub struct Child<'a> {
+pub(crate) struct Child<'a> {
     pub raw: &'a mut super::ArchiveChild<'a>,
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
index 11043b664f5..0e0f2b0eab0 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
@@ -3,13 +3,13 @@
 use libc::c_uint;
 use rustc_span::InnerSpan;
 
-pub use self::Diagnostic::*;
-pub use self::OptimizationDiagnosticKind::*;
+pub(crate) use self::Diagnostic::*;
+use self::OptimizationDiagnosticKind::*;
 use super::{DiagnosticInfo, SMDiagnostic};
 use crate::value::Value;
 
 #[derive(Copy, Clone, Debug)]
-pub enum OptimizationDiagnosticKind {
+pub(crate) enum OptimizationDiagnosticKind {
     OptimizationRemark,
     OptimizationMissed,
     OptimizationAnalysis,
@@ -19,9 +19,10 @@ pub enum OptimizationDiagnosticKind {
     OptimizationRemarkOther,
 }
 
-pub struct OptimizationDiagnostic<'ll> {
+pub(crate) struct OptimizationDiagnostic<'ll> {
     pub kind: OptimizationDiagnosticKind,
     pub pass_name: String,
+    #[expect(dead_code)]
     pub function: &'ll Value,
     pub line: c_uint,
     pub column: c_uint,
@@ -73,14 +74,14 @@ impl<'ll> OptimizationDiagnostic<'ll> {
     }
 }
 
-pub struct SrcMgrDiagnostic {
+pub(crate) struct SrcMgrDiagnostic {
     pub level: super::DiagnosticLevel,
     pub message: String,
     pub source: Option<(String, Vec<InnerSpan>)>,
 }
 
 impl SrcMgrDiagnostic {
-    pub unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
+    pub(crate) unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
         // Recover the post-substitution assembly code from LLVM for better
         // diagnostics.
         let mut have_source = false;
@@ -120,7 +121,7 @@ impl SrcMgrDiagnostic {
 }
 
 #[derive(Clone)]
-pub struct InlineAsmDiagnostic {
+pub(crate) struct InlineAsmDiagnostic {
     pub level: super::DiagnosticLevel,
     pub cookie: u64,
     pub message: String,
@@ -158,7 +159,7 @@ impl InlineAsmDiagnostic {
     }
 }
 
-pub enum Diagnostic<'ll> {
+pub(crate) enum Diagnostic<'ll> {
     Optimization(OptimizationDiagnostic<'ll>),
     InlineAsm(InlineAsmDiagnostic),
     PGO(&'ll DiagnosticInfo),
@@ -166,11 +167,12 @@ pub enum Diagnostic<'ll> {
     Unsupported(&'ll DiagnosticInfo),
 
     /// LLVM has other types that we do not wrap here.
+    #[expect(dead_code)]
     UnknownDiagnostic(&'ll DiagnosticInfo),
 }
 
 impl<'ll> Diagnostic<'ll> {
-    pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
+    pub(crate) unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
         use super::DiagnosticKind as Dk;
 
         unsafe {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
index f6b23862907..79e4cc8aa77 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
@@ -31,20 +31,20 @@ unsafe extern "C" {
 
 #[repr(C)]
 #[derive(Copy, Clone, PartialEq)]
-pub enum LLVMRustVerifierFailureAction {
+pub(crate) enum LLVMRustVerifierFailureAction {
     LLVMAbortProcessAction = 0,
     LLVMPrintMessageAction = 1,
     LLVMReturnStatusAction = 2,
 }
 
 #[cfg(llvm_enzyme)]
-pub use self::Enzyme_AD::*;
+pub(crate) use self::Enzyme_AD::*;
 
 #[cfg(llvm_enzyme)]
-pub mod Enzyme_AD {
+pub(crate) mod Enzyme_AD {
     use libc::c_void;
     unsafe extern "C" {
-        pub fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8);
+        pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8);
     }
     unsafe extern "C" {
         static mut EnzymePrintPerf: c_void;
@@ -56,42 +56,42 @@ pub mod Enzyme_AD {
         static mut EnzymeInline: c_void;
         static mut RustTypeRules: c_void;
     }
-    pub fn set_print_perf(print: bool) {
+    pub(crate) fn set_print_perf(print: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8);
         }
     }
-    pub fn set_print_activity(print: bool) {
+    pub(crate) fn set_print_activity(print: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8);
         }
     }
-    pub fn set_print_type(print: bool) {
+    pub(crate) fn set_print_type(print: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8);
         }
     }
-    pub fn set_print(print: bool) {
+    pub(crate) fn set_print(print: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8);
         }
     }
-    pub fn set_strict_aliasing(strict: bool) {
+    pub(crate) fn set_strict_aliasing(strict: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8);
         }
     }
-    pub fn set_loose_types(loose: bool) {
+    pub(crate) fn set_loose_types(loose: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8);
         }
     }
-    pub fn set_inline(val: bool) {
+    pub(crate) fn set_inline(val: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8);
         }
     }
-    pub fn set_rust_rules(val: bool) {
+    pub(crate) fn set_rust_rules(val: bool) {
         unsafe {
             EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8);
         }
@@ -99,34 +99,34 @@ pub mod Enzyme_AD {
 }
 
 #[cfg(not(llvm_enzyme))]
-pub use self::Fallback_AD::*;
+pub(crate) use self::Fallback_AD::*;
 
 #[cfg(not(llvm_enzyme))]
-pub mod Fallback_AD {
+pub(crate) mod Fallback_AD {
     #![allow(unused_variables)]
 
-    pub fn set_inline(val: bool) {
+    pub(crate) fn set_inline(val: bool) {
         unimplemented!()
     }
-    pub fn set_print_perf(print: bool) {
+    pub(crate) fn set_print_perf(print: bool) {
         unimplemented!()
     }
-    pub fn set_print_activity(print: bool) {
+    pub(crate) fn set_print_activity(print: bool) {
         unimplemented!()
     }
-    pub fn set_print_type(print: bool) {
+    pub(crate) fn set_print_type(print: bool) {
         unimplemented!()
     }
-    pub fn set_print(print: bool) {
+    pub(crate) fn set_print(print: bool) {
         unimplemented!()
     }
-    pub fn set_strict_aliasing(strict: bool) {
+    pub(crate) fn set_strict_aliasing(strict: bool) {
         unimplemented!()
     }
-    pub fn set_loose_types(loose: bool) {
+    pub(crate) fn set_loose_types(loose: bool) {
         unimplemented!()
     }
-    pub fn set_rust_rules(val: bool) {
+    pub(crate) fn set_rust_rules(val: bool) {
         unimplemented!()
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 83efb3ea660..3ce3761944b 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -32,10 +32,10 @@ use crate::llvm;
 
 /// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
 /// which has a different ABI from Rust or C++ `bool`.
-pub type Bool = c_int;
+pub(crate) type Bool = c_int;
 
-pub const True: Bool = 1 as Bool;
-pub const False: Bool = 0 as Bool;
+pub(crate) const True: Bool = 1 as Bool;
+pub(crate) const False: Bool = 0 as Bool;
 
 /// Wrapper for a raw enum value returned from LLVM's C APIs.
 ///
@@ -44,7 +44,7 @@ pub const False: Bool = 0 as Bool;
 /// value and returns it. Instead, return this raw wrapper, then convert to the
 /// Rust-side enum explicitly.
 #[repr(transparent)]
-pub struct RawEnum<T> {
+pub(crate) struct RawEnum<T> {
     value: u32,
     /// We don't own or consume a `T`, but we can produce one.
     _rust_side_type: PhantomData<fn() -> T>,
@@ -64,7 +64,7 @@ impl<T: TryFrom<u32>> RawEnum<T> {
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
 #[allow(dead_code)] // Variants constructed by C++.
-pub enum LLVMRustResult {
+pub(crate) enum LLVMRustResult {
     Success,
     Failure,
 }
@@ -83,7 +83,7 @@ pub enum LLVMRustResult {
 /// C++ API.
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
-pub enum ModuleFlagMergeBehavior {
+pub(crate) enum ModuleFlagMergeBehavior {
     Error = 1,
     Warning = 2,
     Require = 3,
@@ -101,7 +101,7 @@ pub enum ModuleFlagMergeBehavior {
 /// See <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/CallingConv.h>
 #[derive(Copy, Clone, PartialEq, Debug, TryFromU32)]
 #[repr(C)]
-pub enum CallConv {
+pub(crate) enum CallConv {
     CCallConv = 0,
     FastCallConv = 8,
     ColdCallConv = 9,
@@ -126,7 +126,7 @@ pub enum CallConv {
 /// Must match the layout of `LLVMLinkage`.
 #[derive(Copy, Clone, PartialEq, TryFromU32)]
 #[repr(C)]
-pub enum Linkage {
+pub(crate) enum Linkage {
     ExternalLinkage = 0,
     AvailableExternallyLinkage = 1,
     LinkOnceAnyLinkage = 2,
@@ -153,7 +153,7 @@ pub enum Linkage {
 /// Must match the layout of `LLVMVisibility`.
 #[repr(C)]
 #[derive(Copy, Clone, PartialEq, TryFromU32)]
-pub enum Visibility {
+pub(crate) enum Visibility {
     Default = 0,
     Hidden = 1,
     Protected = 2,
@@ -171,8 +171,9 @@ impl Visibility {
 
 /// LLVMUnnamedAddr
 #[repr(C)]
-pub enum UnnamedAddr {
+pub(crate) enum UnnamedAddr {
     No,
+    #[expect(dead_code)]
     Local,
     Global,
 }
@@ -180,7 +181,7 @@ pub enum UnnamedAddr {
 /// LLVMDLLStorageClass
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum DLLStorageClass {
+pub(crate) enum DLLStorageClass {
     #[allow(dead_code)]
     Default = 0,
     DllImport = 1, // Function to be imported from DLL.
@@ -193,7 +194,8 @@ pub enum DLLStorageClass {
 /// though it is not ABI compatible (since it's a C++ enum)
 #[repr(C)]
 #[derive(Copy, Clone, Debug)]
-pub enum AttributeKind {
+#[expect(dead_code, reason = "Some variants are unused, but are kept to match the C++")]
+pub(crate) enum AttributeKind {
     AlwaysInline = 0,
     ByVal = 1,
     Cold = 2,
@@ -241,7 +243,7 @@ pub enum AttributeKind {
 /// LLVMIntPredicate
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum IntPredicate {
+pub(crate) enum IntPredicate {
     IntEQ = 32,
     IntNE = 33,
     IntUGT = 34,
@@ -275,7 +277,7 @@ impl IntPredicate {
 /// LLVMRealPredicate
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum RealPredicate {
+pub(crate) enum RealPredicate {
     RealPredicateFalse = 0,
     RealOEQ = 1,
     RealOGT = 2,
@@ -321,7 +323,8 @@ impl RealPredicate {
 /// LLVMTypeKind
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[repr(C)]
-pub enum TypeKind {
+#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
+pub(crate) enum TypeKind {
     Void = 0,
     Half = 1,
     Float = 2,
@@ -373,7 +376,7 @@ impl TypeKind {
 /// LLVMAtomicRmwBinOp
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum AtomicRmwBinOp {
+pub(crate) enum AtomicRmwBinOp {
     AtomicXchg = 0,
     AtomicAdd = 1,
     AtomicSub = 2,
@@ -409,7 +412,7 @@ impl AtomicRmwBinOp {
 /// LLVMAtomicOrdering
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum AtomicOrdering {
+pub(crate) enum AtomicOrdering {
     #[allow(dead_code)]
     NotAtomic = 0,
     Unordered = 1,
@@ -438,7 +441,7 @@ impl AtomicOrdering {
 /// LLVMRustFileType
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum FileType {
+pub(crate) enum FileType {
     AssemblyFile,
     ObjectFile,
 }
@@ -446,7 +449,8 @@ pub enum FileType {
 /// LLVMMetadataType
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum MetadataType {
+#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
+pub(crate) enum MetadataType {
     MD_dbg = 0,
     MD_tbaa = 1,
     MD_prof = 2,
@@ -470,7 +474,7 @@ pub enum MetadataType {
 /// LLVMRustAsmDialect
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
-pub enum AsmDialect {
+pub(crate) enum AsmDialect {
     Att,
     Intel,
 }
@@ -478,7 +482,7 @@ pub enum AsmDialect {
 /// LLVMRustCodeGenOptLevel
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
-pub enum CodeGenOptLevel {
+pub(crate) enum CodeGenOptLevel {
     None,
     Less,
     Default,
@@ -487,7 +491,7 @@ pub enum CodeGenOptLevel {
 
 /// LLVMRustPassBuilderOptLevel
 #[repr(C)]
-pub enum PassBuilderOptLevel {
+pub(crate) enum PassBuilderOptLevel {
     O0,
     O1,
     O2,
@@ -499,7 +503,7 @@ pub enum PassBuilderOptLevel {
 /// LLVMRustOptStage
 #[derive(PartialEq)]
 #[repr(C)]
-pub enum OptStage {
+pub(crate) enum OptStage {
     PreLinkNoLTO,
     PreLinkThinLTO,
     PreLinkFatLTO,
@@ -509,7 +513,7 @@ pub enum OptStage {
 
 /// LLVMRustSanitizerOptions
 #[repr(C)]
-pub struct SanitizerOptions {
+pub(crate) struct SanitizerOptions {
     pub sanitize_address: bool,
     pub sanitize_address_recover: bool,
     pub sanitize_cfi: bool,
@@ -530,7 +534,7 @@ pub struct SanitizerOptions {
 /// LLVMRustRelocModel
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
-pub enum RelocModel {
+pub(crate) enum RelocModel {
     Static,
     PIC,
     DynamicNoPic,
@@ -542,7 +546,7 @@ pub enum RelocModel {
 /// LLVMRustFloatABI
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
-pub enum FloatAbi {
+pub(crate) enum FloatAbi {
     Default,
     Soft,
     Hard,
@@ -551,7 +555,7 @@ pub enum FloatAbi {
 /// LLVMRustCodeModel
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum CodeModel {
+pub(crate) enum CodeModel {
     Tiny,
     Small,
     Kernel,
@@ -564,7 +568,7 @@ pub enum CodeModel {
 #[derive(Copy, Clone)]
 #[repr(C)]
 #[allow(dead_code)] // Variants constructed by C++.
-pub enum DiagnosticKind {
+pub(crate) enum DiagnosticKind {
     Other,
     InlineAsm,
     StackSize,
@@ -587,7 +591,7 @@ pub enum DiagnosticKind {
 #[derive(Copy, Clone)]
 #[repr(C)]
 #[allow(dead_code)] // Variants constructed by C++.
-pub enum DiagnosticLevel {
+pub(crate) enum DiagnosticLevel {
     Error,
     Warning,
     Note,
@@ -597,7 +601,7 @@ pub enum DiagnosticLevel {
 /// LLVMRustArchiveKind
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum ArchiveKind {
+pub(crate) enum ArchiveKind {
     K_GNU,
     K_BSD,
     K_DARWIN,
@@ -607,15 +611,15 @@ pub enum ArchiveKind {
 
 unsafe extern "C" {
     // LLVMRustThinLTOData
-    pub type ThinLTOData;
+    pub(crate) type ThinLTOData;
 
     // LLVMRustThinLTOBuffer
-    pub type ThinLTOBuffer;
+    pub(crate) type ThinLTOBuffer;
 }
 
 /// LLVMRustThinLTOModule
 #[repr(C)]
-pub struct ThinLTOModule {
+pub(crate) struct ThinLTOModule {
     pub identifier: *const c_char,
     pub data: *const u8,
     pub len: usize,
@@ -624,7 +628,8 @@ pub struct ThinLTOModule {
 /// LLVMThreadLocalMode
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum ThreadLocalMode {
+pub(crate) enum ThreadLocalMode {
+    #[expect(dead_code)]
     NotThreadLocal,
     GeneralDynamic,
     LocalDynamic,
@@ -635,7 +640,7 @@ pub enum ThreadLocalMode {
 /// LLVMRustChecksumKind
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum ChecksumKind {
+pub(crate) enum ChecksumKind {
     None,
     MD5,
     SHA1,
@@ -645,7 +650,7 @@ pub enum ChecksumKind {
 /// LLVMRustMemoryEffects
 #[derive(Copy, Clone)]
 #[repr(C)]
-pub enum MemoryEffects {
+pub(crate) enum MemoryEffects {
     None,
     ReadOnly,
     InaccessibleMemOnly,
@@ -654,7 +659,8 @@ pub enum MemoryEffects {
 /// LLVMOpcode
 #[derive(Copy, Clone, PartialEq, Eq)]
 #[repr(C)]
-pub enum Opcode {
+#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
+pub(crate) enum Opcode {
     Ret = 1,
     Br = 2,
     Switch = 3,
@@ -735,48 +741,48 @@ struct InvariantOpaque<'a> {
 
 // Opaque pointer types
 unsafe extern "C" {
-    pub type Module;
-    pub type Context;
-    pub type Type;
-    pub type Value;
-    pub type ConstantInt;
-    pub type Attribute;
-    pub type Metadata;
-    pub type BasicBlock;
-    pub type Comdat;
+    pub(crate) type Module;
+    pub(crate) type Context;
+    pub(crate) type Type;
+    pub(crate) type Value;
+    pub(crate) type ConstantInt;
+    pub(crate) type Attribute;
+    pub(crate) type Metadata;
+    pub(crate) type BasicBlock;
+    pub(crate) type Comdat;
 }
 #[repr(C)]
-pub struct Builder<'a>(InvariantOpaque<'a>);
+pub(crate) struct Builder<'a>(InvariantOpaque<'a>);
 #[repr(C)]
-pub struct PassManager<'a>(InvariantOpaque<'a>);
+pub(crate) struct PassManager<'a>(InvariantOpaque<'a>);
 unsafe extern "C" {
     pub type TargetMachine;
-    pub type Archive;
+    pub(crate) type Archive;
 }
 #[repr(C)]
-pub struct ArchiveIterator<'a>(InvariantOpaque<'a>);
+pub(crate) struct ArchiveIterator<'a>(InvariantOpaque<'a>);
 #[repr(C)]
-pub struct ArchiveChild<'a>(InvariantOpaque<'a>);
+pub(crate) struct ArchiveChild<'a>(InvariantOpaque<'a>);
 unsafe extern "C" {
-    pub type Twine;
-    pub type DiagnosticInfo;
-    pub type SMDiagnostic;
+    pub(crate) type Twine;
+    pub(crate) type DiagnosticInfo;
+    pub(crate) type SMDiagnostic;
 }
 #[repr(C)]
-pub struct RustArchiveMember<'a>(InvariantOpaque<'a>);
+pub(crate) struct RustArchiveMember<'a>(InvariantOpaque<'a>);
 /// Opaque pointee of `LLVMOperandBundleRef`.
 #[repr(C)]
 pub(crate) struct OperandBundle<'a>(InvariantOpaque<'a>);
 #[repr(C)]
-pub struct Linker<'a>(InvariantOpaque<'a>);
+pub(crate) struct Linker<'a>(InvariantOpaque<'a>);
 
 unsafe extern "C" {
-    pub type DiagnosticHandler;
+    pub(crate) type DiagnosticHandler;
 }
 
-pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
+pub(crate) type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void);
 
-pub mod debuginfo {
+pub(crate) mod debuginfo {
     use std::ptr;
 
     use bitflags::bitflags;
@@ -793,7 +799,7 @@ pub mod debuginfo {
     /// builder reference typically has a shorter lifetime than the LLVM
     /// session (`'ll`) that it participates in.
     #[repr(C)]
-    pub struct DIBuilder<'ll>(InvariantOpaque<'ll>);
+    pub(crate) struct DIBuilder<'ll>(InvariantOpaque<'ll>);
 
     /// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder
     /// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder`
@@ -822,22 +828,22 @@ pub mod debuginfo {
         }
     }
 
-    pub type DIDescriptor = Metadata;
-    pub type DILocation = Metadata;
-    pub type DIScope = DIDescriptor;
-    pub type DIFile = DIScope;
-    pub type DILexicalBlock = DIScope;
-    pub type DISubprogram = DIScope;
-    pub type DIType = DIDescriptor;
-    pub type DIBasicType = DIType;
-    pub type DIDerivedType = DIType;
-    pub type DICompositeType = DIDerivedType;
-    pub type DIVariable = DIDescriptor;
-    pub type DIGlobalVariableExpression = DIDescriptor;
-    pub type DIArray = DIDescriptor;
-    pub type DISubrange = DIDescriptor;
-    pub type DIEnumerator = DIDescriptor;
-    pub type DITemplateTypeParameter = DIDescriptor;
+    pub(crate) type DIDescriptor = Metadata;
+    pub(crate) type DILocation = Metadata;
+    pub(crate) type DIScope = DIDescriptor;
+    pub(crate) type DIFile = DIScope;
+    pub(crate) type DILexicalBlock = DIScope;
+    pub(crate) type DISubprogram = DIScope;
+    pub(crate) type DIType = DIDescriptor;
+    pub(crate) type DIBasicType = DIType;
+    pub(crate) type DIDerivedType = DIType;
+    pub(crate) type DICompositeType = DIDerivedType;
+    pub(crate) type DIVariable = DIDescriptor;
+    pub(crate) type DIGlobalVariableExpression = DIDescriptor;
+    pub(crate) type DIArray = DIDescriptor;
+    pub(crate) type DISubrange = DIDescriptor;
+    pub(crate) type DIEnumerator = DIDescriptor;
+    pub(crate) type DITemplateTypeParameter = DIDescriptor;
 
     bitflags! {
         /// Must match the layout of `LLVMDIFlags` in the LLVM-C API.
@@ -846,7 +852,7 @@ pub mod debuginfo {
         /// assertions in `RustWrapper.cpp` used by `fromRust(LLVMDIFlags)`.
         #[repr(transparent)]
         #[derive(Clone, Copy, Default)]
-        pub struct DIFlags: u32 {
+        pub(crate) struct DIFlags: u32 {
             const FlagZero                = 0;
             const FlagPrivate             = 1;
             const FlagProtected           = 2;
@@ -886,7 +892,7 @@ pub mod debuginfo {
     bitflags! {
         #[repr(transparent)]
         #[derive(Clone, Copy, Default)]
-        pub struct DISPFlags: u32 {
+        pub(crate) struct DISPFlags: u32 {
             const SPFlagZero              = 0;
             const SPFlagVirtual           = 1;
             const SPFlagPureVirtual       = 2;
@@ -900,7 +906,7 @@ pub mod debuginfo {
     /// LLVMRustDebugEmissionKind
     #[derive(Copy, Clone)]
     #[repr(C)]
-    pub enum DebugEmissionKind {
+    pub(crate) enum DebugEmissionKind {
         NoDebug,
         FullDebug,
         LineTablesOnly,
@@ -932,8 +938,9 @@ pub mod debuginfo {
     /// LLVMRustDebugNameTableKind
     #[derive(Clone, Copy)]
     #[repr(C)]
-    pub enum DebugNameTableKind {
+    pub(crate) enum DebugNameTableKind {
         Default,
+        #[expect(dead_code)]
         Gnu,
         None,
     }
@@ -943,7 +950,7 @@ pub mod debuginfo {
 bitflags! {
     #[repr(transparent)]
     #[derive(Default)]
-    pub struct AllocKindFlags : u64 {
+    pub(crate) struct AllocKindFlags : u64 {
         const Unknown = 0;
         const Alloc = 1;
         const Realloc = 1 << 1;
@@ -966,19 +973,20 @@ bitflags! {
 }
 
 unsafe extern "C" {
-    pub type ModuleBuffer;
+    pub(crate) type ModuleBuffer;
 }
 
-pub type SelfProfileBeforePassCallback =
+pub(crate) type SelfProfileBeforePassCallback =
     unsafe extern "C" fn(*mut c_void, *const c_char, *const c_char);
-pub type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void);
+pub(crate) type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void);
 
-pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
-pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
+pub(crate) type GetSymbolsCallback =
+    unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
+pub(crate) type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
 
 #[derive(Copy, Clone)]
 #[repr(transparent)]
-pub struct MetadataKindId(c_uint);
+pub(crate) struct MetadataKindId(c_uint);
 
 impl From<MetadataType> for MetadataKindId {
     fn from(value: MetadataType) -> Self {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index a36226b25a2..6ca81c651ed 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -9,18 +9,18 @@ use libc::c_uint;
 use rustc_abi::{Align, Size, WrappingRange};
 use rustc_llvm::RustString;
 
-pub use self::CallConv::*;
-pub use self::CodeGenOptSize::*;
-pub use self::MetadataType::*;
-pub use self::ffi::*;
+pub(crate) use self::CallConv::*;
+pub(crate) use self::CodeGenOptSize::*;
+pub(crate) use self::MetadataType::*;
+pub(crate) use self::ffi::*;
 use crate::common::AsCCharPtr;
 
-pub mod archive_ro;
-pub mod diagnostic;
-pub mod enzyme_ffi;
+pub(crate) mod archive_ro;
+pub(crate) mod diagnostic;
+pub(crate) mod enzyme_ffi;
 mod ffi;
 
-pub use self::enzyme_ffi::*;
+pub(crate) use self::enzyme_ffi::*;
 
 impl LLVMRustResult {
     pub(crate) fn into_result(self) -> Result<(), ()> {
@@ -127,7 +127,7 @@ pub(crate) fn CreateRangeAttr(llcx: &Context, size: Size, range: WrappingRange)
 }
 
 #[derive(Copy, Clone)]
-pub enum AttributePlace {
+pub(crate) enum AttributePlace {
     ReturnValue,
     Argument(u32),
     Function,
@@ -145,7 +145,7 @@ impl AttributePlace {
 
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
-pub enum CodeGenOptSize {
+pub(crate) enum CodeGenOptSize {
     CodeGenOptSizeNone = 0,
     CodeGenOptSizeDefault = 1,
     CodeGenOptSizeAggressive = 2,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0789.md b/compiler/rustc_error_codes/src/error_codes/E0789.md
index 2c0018cc799..c7bc6cfde51 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0789.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0789.md
@@ -14,7 +14,7 @@ Erroneous code example:
 
 #![unstable(feature = "foo_module", reason = "...", issue = "123")]
 
-#[rustc_allowed_through_unstable_modules]
+#[rustc_allowed_through_unstable_modules = "deprecation message"]
 // #[stable(feature = "foo", since = "1.0")]
 struct Foo;
 // ^^^ error: `rustc_allowed_through_unstable_modules` attribute must be
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 1dd152beb47..990d0f2e028 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -153,7 +153,7 @@ impl Annotatable {
 
     pub fn expect_impl_item(self) -> P<ast::AssocItem> {
         match self {
-            Annotatable::AssocItem(i, AssocCtxt::Impl) => i,
+            Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
             _ => panic!("expected Item"),
         }
     }
@@ -403,6 +403,11 @@ pub trait MacResult {
         None
     }
 
+    /// Creates zero or more impl items.
+    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+        None
+    }
+
     /// Creates zero or more trait items.
     fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
         None
@@ -516,6 +521,10 @@ impl MacResult for MacEager {
         self.impl_items
     }
 
+    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+        self.impl_items
+    }
+
     fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
         self.trait_items
     }
@@ -613,6 +622,10 @@ impl MacResult for DummyResult {
         Some(SmallVec::new())
     }
 
+    fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
+        Some(SmallVec::new())
+    }
+
     fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
         Some(SmallVec::new())
     }
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index e2a55752850..d0bd8a89d9b 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -188,9 +188,15 @@ ast_fragments! {
     ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
         "impl item";
         many fn flat_map_assoc_item;
-        fn visit_assoc_item(AssocCtxt::Impl);
+        fn visit_assoc_item(AssocCtxt::Impl { of_trait: false });
         fn make_impl_items;
     }
+    TraitImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
+        "impl item";
+        many fn flat_map_assoc_item;
+        fn visit_assoc_item(AssocCtxt::Impl { of_trait: true });
+        fn make_trait_impl_items;
+    }
     ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
         "foreign item";
         many fn flat_map_foreign_item;
@@ -257,6 +263,7 @@ impl AstFragmentKind {
             AstFragmentKind::Items
             | AstFragmentKind::TraitItems
             | AstFragmentKind::ImplItems
+            | AstFragmentKind::TraitImplItems
             | AstFragmentKind::ForeignItems
             | AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true },
             AstFragmentKind::Arms
@@ -306,6 +313,9 @@ impl AstFragmentKind {
             AstFragmentKind::ImplItems => {
                 AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect())
             }
+            AstFragmentKind::TraitImplItems => {
+                AstFragment::TraitImplItems(items.map(Annotatable::expect_impl_item).collect())
+            }
             AstFragmentKind::TraitItems => {
                 AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect())
             }
@@ -347,10 +357,10 @@ pub enum InvocationKind {
     },
     Attr {
         attr: ast::Attribute,
-        // Re-insertion position for inert attributes.
+        /// Re-insertion position for inert attributes.
         pos: usize,
         item: Annotatable,
-        // Required for resolving derive helper attributes.
+        /// Required for resolving derive helper attributes.
         derives: Vec<ast::Path>,
     },
     Derive {
@@ -360,6 +370,8 @@ pub enum InvocationKind {
     },
     GlobDelegation {
         item: P<ast::AssocItem>,
+        /// Whether this is a trait impl or an inherent impl
+        of_trait: bool,
     },
 }
 
@@ -388,7 +400,7 @@ impl Invocation {
             InvocationKind::Bang { span, .. } => *span,
             InvocationKind::Attr { attr, .. } => attr.span,
             InvocationKind::Derive { path, .. } => path.span,
-            InvocationKind::GlobDelegation { item } => item.span,
+            InvocationKind::GlobDelegation { item, .. } => item.span,
         }
     }
 
@@ -397,7 +409,7 @@ impl Invocation {
             InvocationKind::Bang { span, .. } => span,
             InvocationKind::Attr { attr, .. } => &mut attr.span,
             InvocationKind::Derive { path, .. } => &mut path.span,
-            InvocationKind::GlobDelegation { item } => &mut item.span,
+            InvocationKind::GlobDelegation { item, .. } => &mut item.span,
         }
     }
 }
@@ -820,7 +832,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 }
                 _ => unreachable!(),
             },
-            InvocationKind::GlobDelegation { item } => {
+            InvocationKind::GlobDelegation { item, of_trait } => {
                 let AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
                 let suffixes = match ext {
                     SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx)
@@ -829,7 +841,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         ExpandResult::Retry(()) => {
                             // Reassemble the original invocation for retrying.
                             return ExpandResult::Retry(Invocation {
-                                kind: InvocationKind::GlobDelegation { item },
+                                kind: InvocationKind::GlobDelegation { item, of_trait },
                                 ..invoc
                             });
                         }
@@ -847,7 +859,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     self.cx, deleg, &item, &suffixes, item.span, true,
                 );
                 fragment_kind.expect_from_annotatables(
-                    single_delegations.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl)),
+                    single_delegations
+                        .map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl { of_trait })),
                 )
             }
         })
@@ -973,6 +986,13 @@ pub fn parse_ast_fragment<'a>(
             }
             AstFragment::ImplItems(items)
         }
+        AstFragmentKind::TraitImplItems => {
+            let mut items = SmallVec::new();
+            while let Some(item) = this.parse_impl_item(ForceCollect::No)? {
+                items.extend(item);
+            }
+            AstFragment::TraitImplItems(items)
+        }
         AstFragmentKind::ForeignItems => {
             let mut items = SmallVec::new();
             while let Some(item) = this.parse_foreign_item(ForceCollect::No)? {
@@ -1355,13 +1375,13 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
     type ItemKind = AssocItemKind;
     const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
     fn to_annotatable(self) -> Annotatable {
-        Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl)
+        Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: false })
     }
     fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
         fragment.make_impl_items()
     }
     fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
-        walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl)
+        walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: false })
     }
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1390,6 +1410,47 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
     }
 }
 
+struct TraitImplItemTag;
+impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItemTag> {
+    type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
+    type ItemKind = AssocItemKind;
+    const KIND: AstFragmentKind = AstFragmentKind::TraitImplItems;
+    fn to_annotatable(self) -> Annotatable {
+        Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: true })
+    }
+    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
+        fragment.make_trait_impl_items()
+    }
+    fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
+        walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: true })
+    }
+    fn is_mac_call(&self) -> bool {
+        matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
+    }
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
+        let item = self.wrapped.into_inner();
+        match item.kind {
+            AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
+            _ => unreachable!(),
+        }
+    }
+    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
+        match &self.wrapped.kind {
+            AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
+            _ => None,
+        }
+    }
+    fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
+        AssocItemKind::Delegation(deleg)
+    }
+    fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
+        AstNodeWrapper::new(P(item), TraitImplItemTag)
+    }
+    fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
+        items.flatten().collect()
+    }
+}
+
 impl InvocationCollectorNode for P<ast::ForeignItem> {
     const KIND: AstFragmentKind = AstFragmentKind::ForeignItems;
     fn to_annotatable(self) -> Annotatable {
@@ -1855,9 +1916,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect_glob_delegation(
         &mut self,
         item: P<ast::AssocItem>,
+        of_trait: bool,
         kind: AstFragmentKind,
     ) -> AstFragment {
-        self.collect(kind, InvocationKind::GlobDelegation { item })
+        self.collect(kind, InvocationKind::GlobDelegation { item, of_trait })
     }
 
     /// If `item` is an attribute invocation, remove the attribute and return it together with
@@ -2030,8 +2092,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                     let Some(suffixes) = &deleg.suffixes else {
                         let traitless_qself =
                             matches!(&deleg.qself, Some(qself) if qself.position == 0);
-                        let item = match node.to_annotatable() {
-                            Annotatable::AssocItem(item, AssocCtxt::Impl) => item,
+                        let (item, of_trait) = match node.to_annotatable() {
+                            Annotatable::AssocItem(item, AssocCtxt::Impl { of_trait }) => {
+                                (item, of_trait)
+                            }
                             ann @ (Annotatable::Item(_)
                             | Annotatable::AssocItem(..)
                             | Annotatable::Stmt(_)) => {
@@ -2046,7 +2110,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                             self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
                             return Default::default();
                         }
-                        return self.collect_glob_delegation(item, Node::KIND).make_ast::<Node>();
+                        return self
+                            .collect_glob_delegation(item, of_trait, Node::KIND)
+                            .make_ast::<Node>();
                     };
 
                     let single_delegations = build_single_delegations::<Node>(
@@ -2126,7 +2192,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
     ) -> SmallVec<[P<ast::AssocItem>; 1]> {
         match ctxt {
             AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
-            AssocCtxt::Impl => self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)),
+            AssocCtxt::Impl { of_trait: false } => {
+                self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
+            }
+            AssocCtxt::Impl { of_trait: true } => {
+                self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
+            }
         }
     }
 
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 3a470924c7f..a60a87244cc 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -86,6 +86,17 @@ pub(crate) fn placeholder(
             kind: ast::AssocItemKind::MacCall(mac_placeholder()),
             tokens: None,
         })]),
+        AstFragmentKind::TraitImplItems => {
+            AstFragment::TraitImplItems(smallvec![P(ast::AssocItem {
+                id,
+                span,
+                ident,
+                vis,
+                attrs,
+                kind: ast::AssocItemKind::MacCall(mac_placeholder()),
+                tokens: None,
+            })])
+        }
         AstFragmentKind::ForeignItems => {
             AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
                 id,
@@ -308,7 +319,8 @@ impl MutVisitor for PlaceholderExpander {
                 let it = self.remove(item.id);
                 match ctxt {
                     AssocCtxt::Trait => it.make_trait_items(),
-                    AssocCtxt::Impl => it.make_impl_items(),
+                    AssocCtxt::Impl { of_trait: false } => it.make_impl_items(),
+                    AssocCtxt::Impl { of_trait: true } => it.make_trait_impl_items(),
                 }
             }
             _ => walk_flat_map_assoc_item(self, item, ctxt),
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 5cccab893bb..333786f0ca3 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -192,7 +192,18 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
             // `TyCtxt` TLS reference here.
             let query_map = current_gcx2.access(|gcx| {
                 tls::enter_context(&tls::ImplicitCtxt::new(gcx), || {
-                    tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs())
+                    tls::with(|tcx| {
+                        match QueryCtxt::new(tcx).collect_active_jobs() {
+                            Ok(query_map) => query_map,
+                            Err(_) => {
+                                // There was an unexpected error collecting all active jobs, which we need
+                                // to find cycles to break.
+                                // We want to avoid panicking in the deadlock handler, so we abort instead.
+                                eprintln!("internal compiler error: failed to get query map in deadlock handler, aborting process");
+                                process::abort();
+                            }
+                        }
+                    })
                 })
             });
             let query_map = FromDyn::from(query_map);
@@ -201,7 +212,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
                 .name("rustc query cycle handler".to_string())
                 .spawn(move || {
                     let on_panic = defer(|| {
-                        eprintln!("query cycle handler thread panicked, aborting process");
+                        eprintln!("internal compiler error: query cycle handler thread panicked, aborting process");
                         // We need to abort here as we failed to resolve the deadlock,
                         // otherwise the compiler could just hang,
                         process::abort();
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 723b894c43b..f9601fa5ef1 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -241,7 +241,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
                 ast_visit::AssocCtxt::Trait => {
                     lint_callback!(cx, check_trait_item, item);
                 }
-                ast_visit::AssocCtxt::Impl => {
+                ast_visit::AssocCtxt::Impl { .. } => {
                     lint_callback!(cx, check_impl_item, item);
                 }
             }
@@ -250,7 +250,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
                 ast_visit::AssocCtxt::Trait => {
                     lint_callback!(cx, check_trait_item_post, item);
                 }
-                ast_visit::AssocCtxt::Impl => {
+                ast_visit::AssocCtxt::Impl { .. } => {
                     lint_callback!(cx, check_impl_item_post, item);
                 }
             }
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index ac9f8d92dac..16c06100808 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -7,7 +7,7 @@ use rustc_parse_format::{ParseMode, Parser, Piece};
 use rustc_session::lint::FutureIncompatibilityReason;
 use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
-use rustc_span::{InnerSpan, Span, Symbol, hygiene, kw, sym};
+use rustc_span::{InnerSpan, Span, Symbol, hygiene, sym};
 use rustc_trait_selection::infer::InferCtxtExt;
 
 use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused};
@@ -167,7 +167,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                     .get_diagnostic_item(sym::Debug)
                     .is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
 
-            let suggest_panic_any = !is_str && panic == sym::std_panic_macro;
+            let suggest_panic_any = !is_str && panic == Some(sym::std_panic_macro);
 
             let fmt_applicability = if suggest_panic_any {
                 // If we can use panic_any, use that as the MachineApplicable suggestion.
@@ -297,10 +297,13 @@ fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char
     ))
 }
 
-fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol, Symbol) {
+fn panic_call<'tcx>(
+    cx: &LateContext<'tcx>,
+    f: &'tcx hir::Expr<'tcx>,
+) -> (Span, Option<Symbol>, Symbol) {
     let mut expn = f.span.ctxt().outer_expn_data();
 
-    let mut panic_macro = kw::Empty;
+    let mut panic_macro = None;
 
     // Unwrap more levels of macro expansion, as panic_2015!()
     // was likely expanded from panic!() and possibly from
@@ -320,7 +323,7 @@ fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span,
             break;
         }
         expn = parent;
-        panic_macro = name;
+        panic_macro = Some(name);
     }
 
     let macro_symbol =
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 572dbae8fd2..aa4c0ef1e1f 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -273,8 +273,9 @@ struct ExtractedHirInfo {
     /// Must have the same context and filename as the body span.
     fn_sig_span_extended: Option<Span>,
     body_span: Span,
-    /// "Holes" are regions within the body span that should not be included in
-    /// coverage spans for this function (e.g. closures and nested items).
+    /// "Holes" are regions within the function body (or its expansions) that
+    /// should not be included in coverage spans for this function
+    /// (e.g. closures and nested items).
     hole_spans: Vec<Span>,
 }
 
@@ -323,7 +324,7 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir
 
     let function_source_hash = hash_mir_source(tcx, hir_body);
 
-    let hole_spans = extract_hole_spans_from_hir(tcx, body_span, hir_body);
+    let hole_spans = extract_hole_spans_from_hir(tcx, hir_body);
 
     ExtractedHirInfo {
         function_source_hash,
@@ -340,14 +341,9 @@ fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) ->
     tcx.hir_owner_nodes(owner).opt_hash_including_bodies.unwrap().to_smaller_hash().as_u64()
 }
 
-fn extract_hole_spans_from_hir<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    body_span: Span, // Usually `hir_body.value.span`, but not always
-    hir_body: &hir::Body<'tcx>,
-) -> Vec<Span> {
+fn extract_hole_spans_from_hir<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &hir::Body<'tcx>) -> Vec<Span> {
     struct HolesVisitor<'tcx> {
         tcx: TyCtxt<'tcx>,
-        body_span: Span,
         hole_spans: Vec<Span>,
     }
 
@@ -387,14 +383,11 @@ fn extract_hole_spans_from_hir<'tcx>(
     }
     impl HolesVisitor<'_> {
         fn visit_hole_span(&mut self, hole_span: Span) {
-            // Discard any holes that aren't directly visible within the body span.
-            if self.body_span.contains(hole_span) && self.body_span.eq_ctxt(hole_span) {
-                self.hole_spans.push(hole_span);
-            }
+            self.hole_spans.push(hole_span);
         }
     }
 
-    let mut visitor = HolesVisitor { tcx, body_span, hole_spans: vec![] };
+    let mut visitor = HolesVisitor { tcx, hole_spans: vec![] };
 
     visitor.visit_body(hir_body);
     visitor.hole_spans
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index b9ed6984ddb..8befe9c5d8d 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -6,10 +6,8 @@ use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
 use tracing::{debug, debug_span, instrument};
 
 use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
-use crate::coverage::spans::from_mir::{
-    ExtractedCovspans, Hole, SpanFromMir, extract_covspans_from_mir,
-};
-use crate::coverage::{ExtractedHirInfo, mappings};
+use crate::coverage::spans::from_mir::{Hole, RawSpanFromMir, SpanFromMir};
+use crate::coverage::{ExtractedHirInfo, mappings, unexpand};
 
 mod from_mir;
 
@@ -19,7 +17,35 @@ pub(super) fn extract_refined_covspans(
     graph: &CoverageGraph,
     code_mappings: &mut impl Extend<mappings::CodeMapping>,
 ) {
-    let ExtractedCovspans { mut covspans } = extract_covspans_from_mir(mir_body, hir_info, graph);
+    let &ExtractedHirInfo { body_span, .. } = hir_info;
+
+    let raw_spans = from_mir::extract_raw_spans_from_mir(mir_body, graph);
+    let mut covspans = raw_spans
+        .into_iter()
+        .filter_map(|RawSpanFromMir { raw_span, bcb }| try {
+            let (span, expn_kind) =
+                unexpand::unexpand_into_body_span_with_expn_kind(raw_span, body_span)?;
+            // Discard any spans that fill the entire body, because they tend
+            // to represent compiler-inserted code, e.g. implicitly returning `()`.
+            if span.source_equal(body_span) {
+                return None;
+            };
+            SpanFromMir { span, expn_kind, bcb }
+        })
+        .collect::<Vec<_>>();
+
+    // Only proceed if we found at least one usable span.
+    if covspans.is_empty() {
+        return;
+    }
+
+    // Also add the adjusted function signature span, if available.
+    // Otherwise, add a fake span at the start of the body, to avoid an ugly
+    // gap between the start of the body and the first real span.
+    // FIXME: Find a more principled way to solve this problem.
+    covspans.push(SpanFromMir::for_fn_sig(
+        hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo()),
+    ));
 
     // First, perform the passes that need macro information.
     covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
@@ -43,7 +69,14 @@ pub(super) fn extract_refined_covspans(
     covspans.dedup_by(|b, a| a.span.source_equal(b.span));
 
     // Sort the holes, and merge overlapping/adjacent holes.
-    let mut holes = hir_info.hole_spans.iter().map(|&span| Hole { span }).collect::<Vec<_>>();
+    let mut holes = hir_info
+        .hole_spans
+        .iter()
+        .copied()
+        // Discard any holes that aren't directly visible within the body span.
+        .filter(|&hole_span| body_span.contains(hole_span) && body_span.eq_ctxt(hole_span))
+        .map(|span| Hole { span })
+        .collect::<Vec<_>>();
     holes.sort_by(|a, b| compare_spans(a.span, b.span));
     holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 73b68d7155c..1faa2171c0b 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -1,3 +1,5 @@
+use std::iter;
+
 use rustc_middle::bug;
 use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::{
@@ -5,87 +7,50 @@ use rustc_middle::mir::{
 };
 use rustc_span::{ExpnKind, Span};
 
-use crate::coverage::ExtractedHirInfo;
-use crate::coverage::graph::{
-    BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
-};
+use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
 use crate::coverage::spans::Covspan;
-use crate::coverage::unexpand::unexpand_into_body_span_with_expn_kind;
 
-pub(crate) struct ExtractedCovspans {
-    pub(crate) covspans: Vec<SpanFromMir>,
+#[derive(Debug)]
+pub(crate) struct RawSpanFromMir {
+    /// A span that has been extracted from a MIR statement/terminator, but
+    /// hasn't been "unexpanded", so it might not lie within the function body
+    /// span and might be part of an expansion with a different context.
+    pub(crate) raw_span: Span,
+    pub(crate) bcb: BasicCoverageBlock,
 }
 
-/// Traverses the MIR body to produce an initial collection of coverage-relevant
-/// spans, each associated with a node in the coverage graph (BCB) and possibly
-/// other metadata.
-pub(crate) fn extract_covspans_from_mir(
-    mir_body: &mir::Body<'_>,
-    hir_info: &ExtractedHirInfo,
+/// Generates an initial set of coverage spans from the statements and
+/// terminators in the function's MIR body, each associated with its
+/// corresponding node in the coverage graph.
+///
+/// This is necessarily an inexact process, because MIR isn't designed to
+/// capture source spans at the level of detail we would want for coverage,
+/// but it's good enough to be better than nothing.
+pub(crate) fn extract_raw_spans_from_mir<'tcx>(
+    mir_body: &mir::Body<'tcx>,
     graph: &CoverageGraph,
-) -> ExtractedCovspans {
-    let &ExtractedHirInfo { body_span, .. } = hir_info;
-
-    let mut covspans = vec![];
+) -> Vec<RawSpanFromMir> {
+    let mut raw_spans = vec![];
 
+    // We only care about blocks that are part of the coverage graph.
     for (bcb, bcb_data) in graph.iter_enumerated() {
-        bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data, &mut covspans);
-    }
+        let make_raw_span = |raw_span: Span| RawSpanFromMir { raw_span, bcb };
 
-    // Only add the signature span if we found at least one span in the body.
-    if !covspans.is_empty() {
-        // If there is no usable signature span, add a fake one (before refinement)
-        // to avoid an ugly gap between the body start and the first real span.
-        // FIXME: Find a more principled way to solve this problem.
-        let fn_sig_span = hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo());
-        covspans.push(SpanFromMir::for_fn_sig(fn_sig_span));
-    }
+        // A coverage graph node can consist of multiple basic blocks.
+        for &bb in &bcb_data.basic_blocks {
+            let bb_data = &mir_body[bb];
 
-    ExtractedCovspans { covspans }
-}
+            let statements = bb_data.statements.iter();
+            raw_spans.extend(statements.filter_map(filtered_statement_span).map(make_raw_span));
 
-// Generate a set of coverage spans from the filtered set of `Statement`s and `Terminator`s of
-// the `BasicBlock`(s) in the given `BasicCoverageBlockData`. One coverage span is generated
-// for each `Statement` and `Terminator`. (Note that subsequent stages of coverage analysis will
-// merge some coverage spans, at which point a coverage span may represent multiple
-// `Statement`s and/or `Terminator`s.)
-fn bcb_to_initial_coverage_spans<'a, 'tcx>(
-    mir_body: &'a mir::Body<'tcx>,
-    body_span: Span,
-    bcb: BasicCoverageBlock,
-    bcb_data: &'a BasicCoverageBlockData,
-    initial_covspans: &mut Vec<SpanFromMir>,
-) {
-    for &bb in &bcb_data.basic_blocks {
-        let data = &mir_body[bb];
-
-        let unexpand = move |expn_span| {
-            unexpand_into_body_span_with_expn_kind(expn_span, body_span)
-                // Discard any spans that fill the entire body, because they tend
-                // to represent compiler-inserted code, e.g. implicitly returning `()`.
-                .filter(|(span, _)| !span.source_equal(body_span))
-        };
-
-        let mut extract_statement_span = |statement| {
-            let expn_span = filtered_statement_span(statement)?;
-            let (span, expn_kind) = unexpand(expn_span)?;
-
-            initial_covspans.push(SpanFromMir::new(span, expn_kind, bcb));
-            Some(())
-        };
-        for statement in data.statements.iter() {
-            extract_statement_span(statement);
+            // There's only one terminator, but wrap it in an iterator to
+            // mirror the handling of statements.
+            let terminator = iter::once(bb_data.terminator());
+            raw_spans.extend(terminator.filter_map(filtered_terminator_span).map(make_raw_span));
         }
-
-        let mut extract_terminator_span = |terminator| {
-            let expn_span = filtered_terminator_span(terminator)?;
-            let (span, expn_kind) = unexpand(expn_span)?;
-
-            initial_covspans.push(SpanFromMir::new(span, expn_kind, bcb));
-            Some(())
-        };
-        extract_terminator_span(data.terminator());
     }
+
+    raw_spans
 }
 
 /// If the MIR `Statement` has a span contributive to computing coverage spans,
@@ -219,7 +184,7 @@ pub(crate) struct SpanFromMir {
 }
 
 impl SpanFromMir {
-    fn for_fn_sig(fn_sig_span: Span) -> Self {
+    pub(crate) fn for_fn_sig(fn_sig_span: Span) -> Self {
         Self::new(fn_sig_span, None, START_BCB)
     }
 
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index f4df4044dd2..123234fedce 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2871,7 +2871,7 @@ impl<'a> Parser<'a> {
                 // Skip every token until next possible arg or end.
                 p.eat_to_tokens(&[exp!(Comma), exp!(CloseParen)]);
                 // Create a placeholder argument for proper arg count (issue #34264).
-                Ok(dummy_arg(Ident::new(kw::Empty, lo.to(p.prev_token.span)), guar))
+                Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar))
             });
             // ...now that we've parsed the first argument, `self` is no longer allowed.
             first_param = false;
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index a72f40cd843..0ee17430aab 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1348,12 +1348,12 @@ pub(crate) struct DuplicateLangItem {
     pub local_span: Option<Span>,
     pub lang_item_name: Symbol,
     pub crate_name: Symbol,
-    pub dependency_of: Symbol,
+    pub dependency_of: Option<Symbol>,
     pub is_local: bool,
     pub path: String,
     pub first_defined_span: Option<Span>,
-    pub orig_crate_name: Symbol,
-    pub orig_dependency_of: Symbol,
+    pub orig_crate_name: Option<Symbol>,
+    pub orig_dependency_of: Option<Symbol>,
     pub orig_is_local: bool,
     pub orig_path: String,
     pub(crate) duplicate: Duplicate,
@@ -1374,10 +1374,16 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for DuplicateLangItem {
         diag.code(E0152);
         diag.arg("lang_item_name", self.lang_item_name);
         diag.arg("crate_name", self.crate_name);
-        diag.arg("dependency_of", self.dependency_of);
+        if let Some(dependency_of) = self.dependency_of {
+            diag.arg("dependency_of", dependency_of);
+        }
         diag.arg("path", self.path);
-        diag.arg("orig_crate_name", self.orig_crate_name);
-        diag.arg("orig_dependency_of", self.orig_dependency_of);
+        if let Some(orig_crate_name) = self.orig_crate_name {
+            diag.arg("orig_crate_name", orig_crate_name);
+        }
+        if let Some(orig_dependency_of) = self.orig_dependency_of {
+            diag.arg("orig_dependency_of", orig_dependency_of);
+        }
         diag.arg("orig_path", self.orig_path);
         if let Some(span) = self.local_span {
             diag.span(span);
@@ -1385,7 +1391,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for DuplicateLangItem {
         if let Some(span) = self.first_defined_span {
             diag.span_note(span, fluent::passes_first_defined_span);
         } else {
-            if self.orig_dependency_of.is_empty() {
+            if self.orig_dependency_of.is_none() {
                 diag.note(fluent::passes_first_defined_crate);
             } else {
                 diag.note(fluent::passes_first_defined_crate_depends);
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index fe1140d893e..9d4b46cd306 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -16,7 +16,7 @@ use rustc_hir::{LangItem, LanguageItems, MethodKind, Target};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_session::cstore::ExternCrate;
-use rustc_span::{Span, kw};
+use rustc_span::Span;
 
 use crate::errors::{
     DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem,
@@ -98,7 +98,7 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
         {
             let lang_item_name = lang_item.name();
             let crate_name = self.tcx.crate_name(item_def_id.krate);
-            let mut dependency_of = kw::Empty;
+            let mut dependency_of = None;
             let is_local = item_def_id.is_local();
             let path = if is_local {
                 String::new()
@@ -112,8 +112,8 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
             };
 
             let first_defined_span = self.item_spans.get(&original_def_id).copied();
-            let mut orig_crate_name = kw::Empty;
-            let mut orig_dependency_of = kw::Empty;
+            let mut orig_crate_name = None;
+            let mut orig_dependency_of = None;
             let orig_is_local = original_def_id.is_local();
             let orig_path = if orig_is_local {
                 String::new()
@@ -127,11 +127,11 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
             };
 
             if first_defined_span.is_none() {
-                orig_crate_name = self.tcx.crate_name(original_def_id.krate);
+                orig_crate_name = Some(self.tcx.crate_name(original_def_id.krate));
                 if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) =
                     self.tcx.extern_crate(original_def_id.krate)
                 {
-                    orig_dependency_of = self.tcx.crate_name(*inner_dependency_of);
+                    orig_dependency_of = Some(self.tcx.crate_name(*inner_dependency_of));
                 }
             }
 
@@ -140,7 +140,7 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
             } else {
                 match self.tcx.extern_crate(item_def_id.krate) {
                     Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => {
-                        dependency_of = self.tcx.crate_name(*inner_dependency_of);
+                        dependency_of = Some(self.tcx.crate_name(*inner_dependency_of));
                         Duplicate::CrateDepends
                     }
                     _ => Duplicate::Crate,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index ed00d97c31d..643b82f4753 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -72,7 +72,9 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
 pub trait DefIdVisitor<'tcx> {
     type Result: VisitorResult = ();
     const SHALLOW: bool = false;
-    const SKIP_ASSOC_TYS: bool = false;
+    fn skip_assoc_tys(&self) -> bool {
+        false
+    }
 
     fn tcx(&self) -> TyCtxt<'tcx>;
     fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
@@ -213,7 +215,7 @@ where
                 }
             }
             ty::Alias(kind @ (ty::Inherent | ty::Weak | ty::Projection), data) => {
-                if V::SKIP_ASSOC_TYS {
+                if self.def_id_visitor.skip_assoc_tys() {
                     // Visitors searching for minimal visibility/reachability want to
                     // conservatively approximate associated types like `Type::Alias`
                     // as visible/reachable even if `Type` is private.
@@ -324,7 +326,9 @@ impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
     for FindMin<'a, 'tcx, VL, SHALLOW>
 {
     const SHALLOW: bool = SHALLOW;
-    const SKIP_ASSOC_TYS: bool = true;
+    fn skip_assoc_tys(&self) -> bool {
+        true
+    }
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -342,7 +346,7 @@ trait VisibilityLike: Sized {
         def_id: LocalDefId,
     ) -> Self;
 
-    // Returns an over-approximation (`SKIP_ASSOC_TYS` = true) of visibility due to
+    // Returns an over-approximation (`skip_assoc_tys()` = true) of visibility due to
     // associated types for which we can't determine visibility precisely.
     fn of_impl<const SHALLOW: bool>(
         def_id: LocalDefId,
@@ -1352,6 +1356,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
     required_effective_vis: Option<EffectiveVisibility>,
     in_assoc_ty: bool,
     in_primary_interface: bool,
+    skip_assoc_tys: bool,
 }
 
 impl SearchInterfaceForPrivateItemsVisitor<'_> {
@@ -1398,6 +1403,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
         self
     }
 
+    fn trait_ref(&mut self) -> &mut Self {
+        self.in_primary_interface = true;
+        if let Some(trait_ref) = self.tcx.impl_trait_ref(self.item_def_id) {
+            let _ = self.visit_trait(trait_ref.instantiate_identity());
+        }
+        self
+    }
+
     fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
         if self.leaks_private_dep(def_id) {
             self.tcx.emit_node_span_lint(
@@ -1495,6 +1508,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
 
 impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
     type Result = ControlFlow<()>;
+    fn skip_assoc_tys(&self) -> bool {
+        self.skip_assoc_tys
+    }
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -1531,6 +1547,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
             required_effective_vis,
             in_assoc_ty: false,
             in_primary_interface: true,
+            skip_assoc_tys: false,
         }
     }
 
@@ -1726,13 +1743,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
                         self.effective_visibilities,
                     );
 
-                    // check that private components do not appear in the generics or predicates of inherent impls
-                    // this check is intentionally NOT performed for impls of traits, per #90586
+                    let mut check = self.check(item.owner_id.def_id, impl_vis, Some(impl_ev));
+                    // Generics and predicates of trait impls are intentionally not checked
+                    // for private components (#90586).
                     if impl_.of_trait.is_none() {
-                        self.check(item.owner_id.def_id, impl_vis, Some(impl_ev))
-                            .generics()
-                            .predicates();
+                        check.generics().predicates();
                     }
+                    // Skip checking private components in associated types, due to lack of full
+                    // normalization they produce very ridiculous false positives.
+                    // FIXME: Remove this when full normalization is implemented.
+                    check.skip_assoc_tys = true;
+                    check.ty().trait_ref();
+
                     for impl_item_ref in impl_.items {
                         let impl_item_vis = if impl_.of_trait.is_none() {
                             min(
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 6fc7f023cf0..55281cd5ac7 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -79,14 +79,20 @@ impl QueryContext for QueryCtxt<'_> {
         tls::with_related_context(self.tcx, |icx| icx.query)
     }
 
-    fn collect_active_jobs(self) -> QueryMap {
+    /// Returns a query map representing active query jobs.
+    /// It returns an incomplete map as an error if it fails
+    /// to take locks.
+    fn collect_active_jobs(self) -> Result<QueryMap, QueryMap> {
         let mut jobs = QueryMap::default();
+        let mut complete = true;
 
         for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
-            collect(self.tcx, &mut jobs);
+            if collect(self.tcx, &mut jobs).is_none() {
+                complete = false;
+            }
         }
 
-        jobs
+        if complete { Ok(jobs) } else { Err(jobs) }
     }
 
     // Interactions with on_disk_cache
@@ -139,7 +145,12 @@ impl QueryContext for QueryCtxt<'_> {
     }
 
     fn depth_limit_error(self, job: QueryJobId) {
-        let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
+        // FIXME: `collect_active_jobs` expects no locks to be held, which doesn't hold for this call.
+        let query_map = match self.collect_active_jobs() {
+            Ok(query_map) => query_map,
+            Err(query_map) => query_map,
+        };
+        let (info, depth) = job.find_dep_kind_root(query_map);
 
         let suggested_limit = match self.recursion_limit() {
             Limit(0) => Limit(2),
@@ -677,7 +688,7 @@ macro_rules! define_queries {
                 }
             }
 
-            pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
+            pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) -> Option<()> {
                 let make_query = |tcx, key| {
                     let kind = rustc_middle::dep_graph::dep_kinds::$name;
                     let name = stringify!($name);
@@ -697,6 +708,7 @@ macro_rules! define_queries {
                         stringify!($name)
                     );
                 }
+                res
             }
 
             pub(crate) fn alloc_self_profile_query_strings<'tcx>(
@@ -756,7 +768,7 @@ macro_rules! define_queries {
 
         // These arrays are used for iteration and can't be indexed by `DepKind`.
 
-        const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] =
+        const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap) -> Option<()>] =
             &[$(query_impl::$name::try_collect_active_jobs),*];
 
         const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 37b305d0a8b..f0cb378f471 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -588,7 +588,12 @@ pub fn print_query_stack<Qcx: QueryContext>(
     // state if it was responsible for triggering the panic.
     let mut count_printed = 0;
     let mut count_total = 0;
-    let query_map = qcx.collect_active_jobs();
+
+    // Make use of a partial query map if we fail to take locks collecting active queries.
+    let query_map = match qcx.collect_active_jobs() {
+        Ok(query_map) => query_map,
+        Err(query_map) => query_map,
+    };
 
     if let Some(ref mut file) = file {
         let _ = writeln!(file, "\n\nquery stack during panic:");
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 2ed0c810b75..0d0c66aa978 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -86,7 +86,7 @@ pub trait QueryContext: HasDepContext {
     /// Get the query information from the TLS context.
     fn current_query_job(self) -> Option<QueryJobId>;
 
-    fn collect_active_jobs(self) -> QueryMap;
+    fn collect_active_jobs(self) -> Result<QueryMap, QueryMap>;
 
     /// Load a side effect associated to the node in the previous session.
     fn load_side_effect(
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index d6b90fbc09f..3a9d80280c2 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -260,8 +260,11 @@ where
     Q: QueryConfig<Qcx>,
     Qcx: QueryContext,
 {
-    let error =
-        try_execute.find_cycle_in_stack(qcx.collect_active_jobs(), &qcx.current_query_job(), span);
+    // Ensure there was no errors collecting all active jobs.
+    // We need the complete map to ensure we find a cycle to break.
+    let query_map = qcx.collect_active_jobs().expect("failed to collect active queries");
+
+    let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span);
     (mk_cycle(query, qcx, error), None)
 }
 
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 42fe01b1c84..97fbf7e378a 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -131,7 +131,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess);
                 return Some(self.new_module(
                     parent,
-                    ModuleKind::Def(def_kind, def_id, self.tcx.item_name(def_id)),
+                    ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
                     expn_id,
                     self.def_span(def_id),
                     // FIXME: Account for `#[no_implicit_prelude]` attributes.
@@ -594,7 +594,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         // HACK(eddyb) unclear how good this is, but keeping `$crate`
                         // in `source` breaks `tests/ui/imports/import-crate-var.rs`,
                         // while the current crate doesn't have a valid `crate_name`.
-                        if crate_name != kw::Empty {
+                        if let Some(crate_name) = crate_name {
                             // `crate_name` should not be interpreted as relative.
                             module_path.push(Segment::from_ident_and_id(
                                 Ident { name: kw::PathRoot, span: source.ident.span },
@@ -603,7 +603,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                             source.ident.name = crate_name;
                         }
                         if rename.is_none() {
-                            ident.name = crate_name;
+                            ident.name = sym::dummy;
                         }
 
                         self.r.dcx().emit_err(errors::CrateImported { span: item.span });
@@ -775,7 +775,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             ItemKind::Mod(.., ref mod_kind) => {
                 let module = self.r.new_module(
                     Some(parent),
-                    ModuleKind::Def(def_kind, def_id, ident.name),
+                    ModuleKind::Def(def_kind, def_id, Some(ident.name)),
                     expansion.to_expn_id(),
                     item.span,
                     parent.no_implicit_prelude
@@ -811,7 +811,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             ItemKind::Enum(_, _) | ItemKind::Trait(..) => {
                 let module = self.r.new_module(
                     Some(parent),
-                    ModuleKind::Def(def_kind, def_id, ident.name),
+                    ModuleKind::Def(def_kind, def_id, Some(ident.name)),
                     expansion.to_expn_id(),
                     item.span,
                     parent.no_implicit_prelude,
@@ -884,10 +884,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             }
 
             // These items do not add names to modules.
-            ItemKind::Impl(box Impl { of_trait: Some(..), .. }) => {
-                self.r.trait_impl_items.insert(local_def_id);
-            }
-            ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
+            ItemKind::Impl(box Impl { of_trait: Some(..), .. })
+            | ItemKind::Impl { .. }
+            | ItemKind::ForeignMod(..)
+            | ItemKind::GlobalAsm(..) => {}
 
             ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
                 unreachable!()
@@ -1377,7 +1377,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 AssocCtxt::Trait => {
                     self.visit_invoc_in_module(item.id);
                 }
-                AssocCtxt::Impl => {
+                AssocCtxt::Impl { .. } => {
                     let invoc_id = item.id.placeholder_to_expn_id();
                     if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
                         self.r
@@ -1397,9 +1397,8 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         let local_def_id = feed.key();
         let def_id = local_def_id.to_def_id();
 
-        if !(ctxt == AssocCtxt::Impl
-            && matches!(item.vis.kind, ast::VisibilityKind::Inherited)
-            && self.r.trait_impl_items.contains(&self.r.tcx.local_parent(local_def_id)))
+        if !(matches!(ctxt, AssocCtxt::Impl { of_trait: true })
+            && matches!(item.vis.kind, ast::VisibilityKind::Inherited))
         {
             // Trait impl item visibility is inherited from its trait when not specified
             // explicitly. In that case we cannot determine it here in early resolve,
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 1c1e8494ffc..51ff4aa834b 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -337,7 +337,8 @@ fn calc_unused_spans(
                     }
                 }
                 contains_self |= use_tree.prefix == kw::SelfLower
-                    && matches!(use_tree.kind, ast::UseTreeKind::Simple(None));
+                    && matches!(use_tree.kind, ast::UseTreeKind::Simple(_))
+                    && !unused_import.unused.contains(&use_tree_id);
                 previous_unused = remove.is_some();
             }
             if unused_spans.is_empty() {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 7decc2a0972..63ea8c4ced1 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -2438,7 +2438,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() else {
             return None;
         };
-        let module_name = crate_module.kind.name().unwrap();
+        let module_name = crate_module.kind.name().unwrap_or(kw::Empty);
         let import_snippet = match import.kind {
             ImportKind::Single { source, target, .. } if source != target => {
                 format!("{source} as {target}")
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f8808582353..76f34d8b24b 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3375,7 +3375,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                             |i, s, c| MethodNotMemberOfTrait(i, s, c),
                         );
 
-                        visit::walk_assoc_item(this, item, AssocCtxt::Impl)
+                        visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true })
                     },
                 );
 
@@ -3409,7 +3409,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                                 |i, s, c| TypeNotMemberOfTrait(i, s, c),
                             );
 
-                            visit::walk_assoc_item(this, item, AssocCtxt::Impl)
+                            visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true })
                         });
                     },
                 );
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 78153fd4174..612e091770f 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -503,18 +503,18 @@ enum ModuleKind {
     ///
     /// * A normal module – either `mod from_file;` or `mod from_block { }` –
     ///   or the crate root (which is conceptually a top-level module).
-    ///   Note that the crate root's [name][Self::name] will be [`kw::Empty`].
+    ///   The crate root will have `None` for the symbol.
     /// * A trait or an enum (it implicitly contains associated types, methods and variant
     ///   constructors).
-    Def(DefKind, DefId, Symbol),
+    Def(DefKind, DefId, Option<Symbol>),
 }
 
 impl ModuleKind {
     /// Get name of the module.
     fn name(&self) -> Option<Symbol> {
-        match self {
+        match *self {
             ModuleKind::Block => None,
-            ModuleKind::Def(.., name) => Some(*name),
+            ModuleKind::Def(.., name) => name,
         }
     }
 }
@@ -1191,10 +1191,6 @@ pub struct Resolver<'ra, 'tcx> {
     /// and how the `impl Trait` fragments were introduced.
     invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
 
-    /// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
-    /// FIXME: Replace with a more general AST map (together with some other fields).
-    trait_impl_items: FxHashSet<LocalDefId>,
-
     legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
     /// Amount of lifetime parameters for each item in the crate.
     item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
@@ -1402,7 +1398,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         let mut module_self_bindings = FxHashMap::default();
         let graph_root = arenas.new_module(
             None,
-            ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
+            ModuleKind::Def(DefKind::Mod, root_def_id, None),
             ExpnId::root(),
             crate_span,
             attr::contains_name(attrs, sym::no_implicit_prelude),
@@ -1411,7 +1407,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         );
         let empty_module = arenas.new_module(
             None,
-            ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
+            ModuleKind::Def(DefKind::Mod, root_def_id, None),
             ExpnId::root(),
             DUMMY_SP,
             true,
@@ -1558,7 +1554,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             def_id_to_node_id,
             placeholder_field_indices: Default::default(),
             invocation_parents,
-            trait_impl_items: Default::default(),
             legacy_const_generic_args: Default::default(),
             item_generics_num_lifetimes: Default::default(),
             main_def: Default::default(),
@@ -2286,7 +2281,8 @@ fn module_to_string(mut module: Module<'_>) -> Option<String> {
     loop {
         if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
-                names.push(name);
+                // `unwrap` is safe: the presence of a parent means it's not the crate root.
+                names.push(name.unwrap());
                 module = parent
             } else {
                 break;
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 3637854f120..d0ffef798cf 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -168,7 +168,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
         hygiene::update_dollar_crate_names(|ctxt| {
             let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
             match self.resolve_crate_root(ident).kind {
-                ModuleKind::Def(.., name) if name != kw::Empty => name,
+                ModuleKind::Def(.., name) if let Some(name) = name => name,
                 _ => kw::Crate,
             }
         });
@@ -264,7 +264,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
             }
             InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang),
             InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive),
-            InvocationKind::GlobDelegation { ref item } => {
+            InvocationKind::GlobDelegation { ref item, .. } => {
                 let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
                 deleg_impl = Some(self.invocation_parent(invoc_id));
                 // It is sufficient to consider glob delegation a bang macro for now.
@@ -1067,11 +1067,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             );
             if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) {
                 let location = match parent_scope.module.kind {
-                    ModuleKind::Def(_, _, name) if name == kw::Empty => {
-                        "the crate root".to_string()
-                    }
                     ModuleKind::Def(kind, def_id, name) => {
-                        format!("{} `{name}`", kind.descr(def_id))
+                        if let Some(name) = name {
+                            format!("{} `{name}`", kind.descr(def_id))
+                        } else {
+                            "the crate root".to_string()
+                        }
                     }
                     ModuleKind::Block => "this scope".to_string(),
                 };
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index 7aa5ed60d04..2f027be6928 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1623,6 +1623,8 @@ impl Ipv6Addr {
             // IANA says N/A.
             || matches!(self.segments(), [0x2002, _, _, _, _, _, _, _])
             || self.is_documentation()
+            // Segment Routing (SRv6) SIDs (`5f00::/16`)
+            || matches!(self.segments(), [0x5f00, ..])
             || self.is_unique_local()
             || self.is_unicast_link_local())
     }
diff --git a/library/coretests/tests/net/ip_addr.rs b/library/coretests/tests/net/ip_addr.rs
index f01b43282ec..3fec59d67b7 100644
--- a/library/coretests/tests/net/ip_addr.rs
+++ b/library/coretests/tests/net/ip_addr.rs
@@ -689,6 +689,8 @@ fn ipv6_properties() {
 
     check!("2002::", &[0x20, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
 
+    check!("5f00::", &[0x5f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
+
     check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
 
     check!(
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index a5cfc542a17..5749d8c63fa 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -624,7 +624,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         // TODO(calebcartwright): Not sure the skip spans are correct
         let (ai, skip_span, assoc_ctxt) = match visitor_kind {
             AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
-            AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl),
+            // There is no difference between trait and inherent assoc item formatting
+            AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl { of_trait: false }),
             _ => unreachable!(),
         };
         skip_out_of_file_lines_range_visitor!(self, ai.span);
diff --git a/tests/ui/attributes/crate-name-empty.rs b/tests/ui/attributes/crate-name-empty.rs
new file mode 100644
index 00000000000..dfba77a52de
--- /dev/null
+++ b/tests/ui/attributes/crate-name-empty.rs
@@ -0,0 +1,5 @@
+// Ensure we reject `#![crate_name = ""]`.
+
+#![crate_name = ""] //~ ERROR crate name must not be empty
+
+fn main() {}
diff --git a/tests/ui/attributes/crate-name-empty.stderr b/tests/ui/attributes/crate-name-empty.stderr
new file mode 100644
index 00000000000..509a42d05f7
--- /dev/null
+++ b/tests/ui/attributes/crate-name-empty.stderr
@@ -0,0 +1,8 @@
+error: crate name must not be empty
+  --> $DIR/crate-name-empty.rs:3:1
+   |
+LL | #![crate_name = ""]
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/unused/lint-unused-imports-self-single.fixed b/tests/ui/lint/unused/lint-unused-imports-self-single.fixed
new file mode 100644
index 00000000000..361548bfdc1
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-imports-self-single.fixed
@@ -0,0 +1,29 @@
+//@ run-rustfix
+
+#![deny(unused_imports)]
+#![allow(unreachable_code)]
+
+use std::collections::{self as coll};
+//~^ ERROR unused import: `HashMap`
+
+//~^ ERROR unused import: `self as std_io`
+
+use std::sync::Mutex;
+//~^ ERROR unused import: `self as std_sync`
+
+use std::sync::mpsc::Sender;
+//~^ ERROR unused import: `self as std_sync_mpsc`
+
+use std::collections::hash_map::{self as std_coll_hm};
+//~^ ERROR unused import: `Keys`
+
+use std::borrow::Cow;
+//~^ ERROR unused import: `self`
+
+fn main() {
+    let _ = coll::BTreeSet::<String>::default();
+    let _ = Mutex::new(String::new());
+    let _: Cow<'static, str> = "foo".into();
+    let _: Sender<u32> = todo!();
+    let _: std_coll_hm::Entry<'static, u32, u32> = todo!();
+}
diff --git a/tests/ui/lint/unused/lint-unused-imports-self-single.rs b/tests/ui/lint/unused/lint-unused-imports-self-single.rs
new file mode 100644
index 00000000000..d03d3822e04
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-imports-self-single.rs
@@ -0,0 +1,30 @@
+//@ run-rustfix
+
+#![deny(unused_imports)]
+#![allow(unreachable_code)]
+
+use std::collections::{HashMap, self as coll};
+//~^ ERROR unused import: `HashMap`
+
+use std::io::{self as std_io};
+//~^ ERROR unused import: `self as std_io`
+
+use std::sync::{Mutex, self as std_sync};
+//~^ ERROR unused import: `self as std_sync`
+
+use std::sync::{mpsc::{self as std_sync_mpsc, Sender}};
+//~^ ERROR unused import: `self as std_sync_mpsc`
+
+use std::collections::{hash_map::{self as std_coll_hm, Keys}};
+//~^ ERROR unused import: `Keys`
+
+use std::borrow::{self, Cow};
+//~^ ERROR unused import: `self`
+
+fn main() {
+    let _ = coll::BTreeSet::<String>::default();
+    let _ = Mutex::new(String::new());
+    let _: Cow<'static, str> = "foo".into();
+    let _: Sender<u32> = todo!();
+    let _: std_coll_hm::Entry<'static, u32, u32> = todo!();
+}
diff --git a/tests/ui/lint/unused/lint-unused-imports-self-single.stderr b/tests/ui/lint/unused/lint-unused-imports-self-single.stderr
new file mode 100644
index 00000000000..70a9b78a664
--- /dev/null
+++ b/tests/ui/lint/unused/lint-unused-imports-self-single.stderr
@@ -0,0 +1,44 @@
+error: unused import: `HashMap`
+  --> $DIR/lint-unused-imports-self-single.rs:6:24
+   |
+LL | use std::collections::{HashMap, self as coll};
+   |                        ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-imports-self-single.rs:3:9
+   |
+LL | #![deny(unused_imports)]
+   |         ^^^^^^^^^^^^^^
+
+error: unused import: `self as std_io`
+  --> $DIR/lint-unused-imports-self-single.rs:9:15
+   |
+LL | use std::io::{self as std_io};
+   |               ^^^^^^^^^^^^^^
+
+error: unused import: `self as std_sync`
+  --> $DIR/lint-unused-imports-self-single.rs:12:24
+   |
+LL | use std::sync::{Mutex, self as std_sync};
+   |                        ^^^^^^^^^^^^^^^^
+
+error: unused import: `self as std_sync_mpsc`
+  --> $DIR/lint-unused-imports-self-single.rs:15:24
+   |
+LL | use std::sync::{mpsc::{self as std_sync_mpsc, Sender}};
+   |                        ^^^^^^^^^^^^^^^^^^^^^
+
+error: unused import: `Keys`
+  --> $DIR/lint-unused-imports-self-single.rs:18:56
+   |
+LL | use std::collections::{hash_map::{self as std_coll_hm, Keys}};
+   |                                                        ^^^^
+
+error: unused import: `self`
+  --> $DIR/lint-unused-imports-self-single.rs:21:19
+   |
+LL | use std::borrow::{self, Cow};
+   |                   ^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs
index 112eaf528be..877029f3de3 100644
--- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs
+++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs
@@ -77,15 +77,14 @@ pub type Alias = OtherType;
 
 pub struct PublicWithPrivateImpl;
 
-// FIXME: This should trigger.
-// See https://github.com/rust-lang/rust/issues/71043
 impl OtherTrait for PublicWithPrivateImpl {}
+//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
 
 pub trait PubTraitOnPrivate {}
 
-// FIXME: This should trigger.
-// See https://github.com/rust-lang/rust/issues/71043
 impl PubTraitOnPrivate for OtherType {}
+//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface
+//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface
 
 pub struct AllowedPrivType {
     #[allow(exported_private_dependencies)]
diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr
index 53d461a5774..adfe13424cd 100644
--- a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr
+++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr
@@ -70,5 +70,25 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface
 LL | pub type Alias = OtherType;
    | ^^^^^^^^^^^^^^
 
-error: aborting due to 11 previous errors
+error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
+  --> $DIR/pub-priv1.rs:80:1
+   |
+LL | impl OtherTrait for PublicWithPrivateImpl {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: type `OtherType` from private dependency 'priv_dep' in public interface
+  --> $DIR/pub-priv1.rs:85:1
+   |
+LL | impl PubTraitOnPrivate for OtherType {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: type `OtherType` from private dependency 'priv_dep' in public interface
+  --> $DIR/pub-priv1.rs:85:1
+   |
+LL | impl PubTraitOnPrivate for OtherType {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 14 previous errors