about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs114
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs53
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs32
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs38
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs15
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0515.md9
-rw-r--r--compiler/rustc_hir/src/hir.rs148
-rw-r--r--compiler/rustc_hir/src/intravisit.rs45
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/collect/dump.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs6
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs63
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs18
-rw-r--r--compiler/rustc_lint/src/default_could_be_derived.rs6
-rw-r--r--compiler/rustc_lint/src/internal.rs6
-rw-r--r--compiler/rustc_lint/src/multiple_supertrait_upcastable.rs4
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs6
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs14
-rw-r--r--compiler/rustc_lint/src/types.rs10
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map.rs36
-rw-r--r--compiler/rustc_middle/src/thir.rs23
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs59
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs8
-rw-r--r--compiler/rustc_mir_build/src/builder/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs6
-rw-r--r--compiler/rustc_passes/src/check_attr.rs16
-rw-r--r--compiler/rustc_passes/src/dead.rs8
-rw-r--r--compiler/rustc_passes/src/reachable.rs4
-rw-r--r--compiler/rustc_passes/src/stability.rs6
-rw-r--r--compiler/rustc_privacy/src/lib.rs23
-rw-r--r--compiler/rustc_target/src/target_features.rs22
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs50
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs2
53 files changed, 587 insertions, 487 deletions
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index d1e23bf2522..26c0e7e5f82 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -164,7 +164,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     fn visit_item(&mut self, i: &'hir Item<'hir>) {
         debug_assert_eq!(i.owner_id, self.owner);
         self.with_parent(i.hir_id(), |this| {
-            if let ItemKind::Struct(struct_def, _) = &i.kind {
+            if let ItemKind::Struct(_, struct_def, _) = &i.kind {
                 // If this is a tuple or unit-like struct, register the constructor.
                 if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
                     this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 3b2e8581c00..bd011d59aaa 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -111,6 +111,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
     }
 
     fn lower_foreign_item(&mut self, item: &ForeignItem) {
+        debug_assert_ne!(item.ident.name, kw::Empty);
         self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
     }
 }
@@ -154,14 +155,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
-        let mut ident = i.ident;
         let vis_span = self.lower_span(i.vis.span);
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
-        let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
+        let kind = self.lower_item_kind(i.span, i.id, hir_id, i.ident, attrs, vis_span, &i.kind);
         let item = hir::Item {
             owner_id: hir_id.expect_owner(),
-            ident: self.lower_ident(ident),
             kind,
             vis_span,
             span: self.lower_span(i.span),
@@ -174,25 +173,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
         span: Span,
         id: NodeId,
         hir_id: hir::HirId,
-        ident: &mut Ident,
+        ident: Ident,
         attrs: &'hir [hir::Attribute],
         vis_span: Span,
         i: &ItemKind,
     ) -> hir::ItemKind<'hir> {
         match i {
-            ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name),
+            ItemKind::ExternCrate(orig_name) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
+                hir::ItemKind::ExternCrate(*orig_name, ident)
+            }
             ItemKind::Use(use_tree) => {
+                debug_assert_eq!(ident.name, kw::Empty);
                 // Start with an empty prefix.
                 let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
 
-                self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
+                self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
             }
             ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (ty, body_id) =
                     self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
-                hir::ItemKind::Static(ty, *m, body_id)
+                hir::ItemKind::Static(ident, ty, *m, body_id)
             }
             ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (generics, (ty, body_id)) = self.lower_generics(
                     generics,
                     id,
@@ -201,7 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
                     },
                 );
-                hir::ItemKind::Const(ty, generics, body_id)
+                hir::ItemKind::Const(ident, ty, generics, body_id)
             }
             ItemKind::Fn(box Fn {
                 sig: FnSig { decl, header, span: fn_sig_span },
@@ -211,6 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 define_opaque,
                 ..
             }) => {
+                debug_assert_ne!(ident.name, kw::Empty);
                 self.with_new_scopes(*fn_sig_span, |this| {
                     // Note: we don't need to change the return type from `T` to
                     // `impl Future<Output = T>` here because lower_body
@@ -238,28 +247,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         span: this.lower_span(*fn_sig_span),
                     };
                     this.lower_define_opaque(hir_id, &define_opaque);
-                    hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
+                    let ident = this.lower_ident(ident);
+                    hir::ItemKind::Fn {
+                        ident,
+                        sig,
+                        generics,
+                        body: body_id,
+                        has_body: body.is_some(),
+                    }
                 })
             }
-            ItemKind::Mod(_, mod_kind) => match mod_kind {
-                ModKind::Loaded(items, _, spans, _) => {
-                    hir::ItemKind::Mod(self.lower_mod(items, spans))
+            ItemKind::Mod(_, mod_kind) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
+                match mod_kind {
+                    ModKind::Loaded(items, _, spans, _) => {
+                        hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
+                    }
+                    ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
                 }
-                ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
-            },
-            ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
-                abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
-                items: self
-                    .arena
-                    .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
-            },
+            }
+            ItemKind::ForeignMod(fm) => {
+                debug_assert_eq!(ident.name, kw::Empty);
+                hir::ItemKind::ForeignMod {
+                    abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
+                    items: self
+                        .arena
+                        .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
+                }
+            }
             ItemKind::GlobalAsm(asm) => {
+                debug_assert_eq!(ident.name, kw::Empty);
                 let asm = self.lower_inline_asm(span, asm);
                 let fake_body =
                     self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
                 hir::ItemKind::GlobalAsm { asm, fake_body }
             }
             ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
+                debug_assert_ne!(ident.name, kw::Empty);
                 // We lower
                 //
                 // type Foo = impl Trait
@@ -268,6 +293,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 //
                 // type Foo = Foo1
                 // opaque type Foo1: Trait
+                let ident = self.lower_ident(ident);
                 let mut generics = generics.clone();
                 add_ty_alias_where_clause(&mut generics, *where_clauses, true);
                 let (generics, ty) = self.lower_generics(
@@ -293,9 +319,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ),
                     },
                 );
-                hir::ItemKind::TyAlias(ty, generics)
+                hir::ItemKind::TyAlias(ident, ty, generics)
             }
             ItemKind::Enum(enum_definition, generics) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (generics, variants) = self.lower_generics(
                     generics,
                     id,
@@ -306,25 +334,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         )
                     },
                 );
-                hir::ItemKind::Enum(hir::EnumDef { variants }, generics)
+                hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics)
             }
             ItemKind::Struct(struct_def, generics) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (generics, struct_def) = self.lower_generics(
                     generics,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, struct_def),
                 );
-                hir::ItemKind::Struct(struct_def, generics)
+                hir::ItemKind::Struct(ident, struct_def, generics)
             }
             ItemKind::Union(vdata, generics) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (generics, vdata) = self.lower_generics(
                     generics,
                     id,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, vdata),
                 );
-                hir::ItemKind::Union(vdata, generics)
+                hir::ItemKind::Union(ident, vdata, generics)
             }
             ItemKind::Impl(box Impl {
                 safety,
@@ -336,6 +368,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 self_ty: ty,
                 items: impl_items,
             }) => {
+                debug_assert_eq!(ident.name, kw::Empty);
                 // Lower the "impl header" first. This ordering is important
                 // for in-band lifetimes! Consider `'a` here:
                 //
@@ -401,6 +434,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }))
             }
             ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (generics, (safety, items, bounds)) = self.lower_generics(
                     generics,
                     id,
@@ -417,9 +452,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         (safety, items, bounds)
                     },
                 );
-                hir::ItemKind::Trait(*is_auto, safety, generics, bounds, items)
+                hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
             }
             ItemKind::TraitAlias(generics, bounds) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let (generics, bounds) = self.lower_generics(
                     generics,
                     id,
@@ -431,9 +468,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         )
                     },
                 );
-                hir::ItemKind::TraitAlias(generics, bounds)
+                hir::ItemKind::TraitAlias(ident, generics, bounds)
             }
             ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
+                debug_assert_ne!(ident.name, kw::Empty);
+                let ident = self.lower_ident(ident);
                 let body = P(self.lower_delim_args(body));
                 let def_id = self.local_def_id(id);
                 let def_kind = self.tcx.def_kind(def_id);
@@ -444,11 +483,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     );
                 };
                 let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
-                hir::ItemKind::Macro(macro_def, macro_kind)
+                hir::ItemKind::Macro(ident, macro_def, macro_kind)
             }
             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);
                 hir::ItemKind::Fn {
+                    ident,
                     sig: delegation_results.sig,
                     generics: delegation_results.generics,
                     body: delegation_results.body_id,
@@ -479,7 +521,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         prefix: &Path,
         id: NodeId,
         vis_span: Span,
-        ident: &mut Ident,
         attrs: &'hir [hir::Attribute],
     ) -> hir::ItemKind<'hir> {
         let path = &tree.prefix;
@@ -487,7 +528,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         match tree.kind {
             UseTreeKind::Simple(rename) => {
-                *ident = tree.ident();
+                let mut ident = tree.ident();
 
                 // First, apply the prefix to the path.
                 let mut path = Path { segments, span: path.span, tokens: None };
@@ -498,13 +539,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 {
                     let _ = path.segments.pop();
                     if rename.is_none() {
-                        *ident = path.segments.last().unwrap().ident;
+                        ident = path.segments.last().unwrap().ident;
                     }
                 }
 
                 let res = self.lower_import_res(id, path.span);
                 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
-                hir::ItemKind::Use(path, hir::UseKind::Single)
+                let ident = self.lower_ident(ident);
+                hir::ItemKind::Use(path, hir::UseKind::Single(ident))
             }
             UseTreeKind::Glob => {
                 let res = self.expect_full_res(id);
@@ -551,20 +593,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     // own its own names, we have to adjust the owner before
                     // lowering the rest of the import.
                     self.with_hir_id_owner(id, |this| {
-                        let mut ident = *ident;
-
                         // `prefix` is lowered multiple times, but in different HIR owners.
                         // So each segment gets renewed `HirId` with the same
                         // `ItemLocalId` and the new owner. (See `lower_node_id`)
-                        let kind =
-                            this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
+                        let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
                         if !attrs.is_empty() {
                             this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
                         }
 
                         let item = hir::Item {
                             owner_id: hir::OwnerId { def_id: new_hir_id },
-                            ident: this.lower_ident(ident),
                             kind,
                             vis_span,
                             span: this.lower_span(use_tree.span),
@@ -604,7 +642,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             hir::ItemKind::Impl(impl_) => {
                 self.is_in_trait_impl = impl_.of_trait.is_some();
             }
-            hir::ItemKind::Trait(_, _, _, _, _) => {}
+            hir::ItemKind::Trait(..) => {}
             kind => {
                 span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
             }
@@ -760,6 +798,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
+        debug_assert_ne!(i.ident.name, kw::Empty);
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
         let trait_item_def_id = hir_id.expect_owner();
@@ -907,6 +946,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_impl_item(&mut self, i: &AssocItem) -> &'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;
         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 3d8883e011f..fddddf404db 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -691,7 +691,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             true,
             td.is_local(),
             td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) {
-                Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. }) => {
+                Node::Item(hir::Item {
+                    kind: hir::ItemKind::Trait(_, _, _, _, _, items), ..
+                }) => {
                     let mut f_in_trait_opt = None;
                     for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
                         let hi = fi.hir_id();
@@ -980,7 +982,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             let arg = match tcx.hir_get_if_local(callee_def_id) {
                 Some(
                     hir::Node::Item(hir::Item {
-                        ident, kind: hir::ItemKind::Fn { sig, .. }, ..
+                        kind: hir::ItemKind::Fn { ident, sig, .. }, ..
                     })
                     | hir::Node::TraitItem(hir::TraitItem {
                         ident,
@@ -1021,7 +1023,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             // return type.
             match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) {
                 hir::Node::Item(hir::Item {
-                    ident, kind: hir::ItemKind::Fn { sig, .. }, ..
+                    kind: hir::ItemKind::Fn { ident, sig, .. }, ..
                 })
                 | hir::Node::TraitItem(hir::TraitItem {
                     ident,
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 60af462b6b6..34c84c64070 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -389,11 +389,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
         mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
     ) -> io::Result<()> {
         let mut archive_path = archive_path.to_path_buf();
-        if self.sess.target.llvm_target.contains("-apple-macosx") {
-            if let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)?
-            {
-                archive_path = new_archive_path
-            }
+        if self.sess.target.llvm_target.contains("-apple-macosx")
+            && let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)?
+        {
+            archive_path = new_archive_path
         }
 
         if self.src_archives.iter().any(|archive| archive.0 == archive_path) {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 5f85c10636e..74597f6263d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -151,17 +151,17 @@ pub fn link_binary(
                 sess.dcx().emit_artifact_notification(&out_filename, "link");
             }
 
-            if sess.prof.enabled() {
-                if let Some(artifact_name) = out_filename.file_name() {
-                    // Record size for self-profiling
-                    let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0);
-
-                    sess.prof.artifact_size(
-                        "linked_artifact",
-                        artifact_name.to_string_lossy(),
-                        file_size,
-                    );
-                }
+            if sess.prof.enabled()
+                && let Some(artifact_name) = out_filename.file_name()
+            {
+                // Record size for self-profiling
+                let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0);
+
+                sess.prof.artifact_size(
+                    "linked_artifact",
+                    artifact_name.to_string_lossy(),
+                    file_size,
+                );
             }
 
             if output.is_stdout() {
@@ -186,16 +186,12 @@ pub fn link_binary(
 
         let maybe_remove_temps_from_module =
             |preserve_objects: bool, preserve_dwarf_objects: bool, module: &CompiledModule| {
-                if !preserve_objects {
-                    if let Some(ref obj) = module.object {
-                        ensure_removed(sess.dcx(), obj);
-                    }
+                if !preserve_objects && let Some(ref obj) = module.object {
+                    ensure_removed(sess.dcx(), obj);
                 }
 
-                if !preserve_dwarf_objects {
-                    if let Some(ref dwo_obj) = module.dwarf_object {
-                        ensure_removed(sess.dcx(), dwo_obj);
-                    }
+                if !preserve_dwarf_objects && let Some(ref dwo_obj) = module.dwarf_object {
+                    ensure_removed(sess.dcx(), dwo_obj);
                 }
             };
 
@@ -2116,11 +2112,11 @@ fn add_local_crate_metadata_objects(
     // When linking a dynamic library, we put the metadata into a section of the
     // executable. This metadata is in a separate object file from the main
     // object file, so we link that in here.
-    if crate_type == CrateType::Dylib || crate_type == CrateType::ProcMacro {
-        if let Some(obj) = codegen_results.metadata_module.as_ref().and_then(|m| m.object.as_ref())
-        {
-            cmd.add_object(obj);
-        }
+    if matches!(crate_type, CrateType::Dylib | CrateType::ProcMacro)
+        && let Some(m) = &codegen_results.metadata_module
+        && let Some(obj) = &m.object
+    {
+        cmd.add_object(obj);
     }
 }
 
@@ -2540,10 +2536,11 @@ fn add_order_independent_options(
 
     cmd.output_filename(out_filename);
 
-    if crate_type == CrateType::Executable && sess.target.is_like_windows {
-        if let Some(ref s) = codegen_results.crate_info.windows_subsystem {
-            cmd.subsystem(s);
-        }
+    if crate_type == CrateType::Executable
+        && sess.target.is_like_windows
+        && let Some(s) = &codegen_results.crate_info.windows_subsystem
+    {
+        cmd.subsystem(s);
     }
 
     // Try to strip as much out of the generated object by removing unused
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index a8405a2aec9..e2a59c6efb8 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -111,24 +111,22 @@ pub(crate) fn get_linker<'a>(
     // PATH for the child.
     let mut new_path = sess.get_tools_search_paths(self_contained);
     let mut msvc_changed_path = false;
-    if sess.target.is_like_msvc {
-        if let Some(ref tool) = msvc_tool {
-            cmd.args(tool.args());
-            for (k, v) in tool.env() {
-                if k == "PATH" {
-                    new_path.extend(env::split_paths(v));
-                    msvc_changed_path = true;
-                } else {
-                    cmd.env(k, v);
-                }
+    if sess.target.is_like_msvc
+        && let Some(ref tool) = msvc_tool
+    {
+        cmd.args(tool.args());
+        for (k, v) in tool.env() {
+            if k == "PATH" {
+                new_path.extend(env::split_paths(v));
+                msvc_changed_path = true;
+            } else {
+                cmd.env(k, v);
             }
         }
     }
 
-    if !msvc_changed_path {
-        if let Some(path) = env::var_os("PATH") {
-            new_path.extend(env::split_paths(&path));
-        }
+    if !msvc_changed_path && let Some(path) = env::var_os("PATH") {
+        new_path.extend(env::split_paths(&path));
     }
     cmd.env("PATH", env::join_paths(new_path).unwrap());
 
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 9cc737d194c..2ec203458a3 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -566,16 +566,13 @@ fn produce_final_output_artifacts(
 
     // Produce final compile outputs.
     let copy_gracefully = |from: &Path, to: &OutFileName| match to {
-        OutFileName::Stdout => {
-            if let Err(e) = copy_to_stdout(from) {
-                sess.dcx().emit_err(errors::CopyPath::new(from, to.as_path(), e));
-            }
+        OutFileName::Stdout if let Err(e) = copy_to_stdout(from) => {
+            sess.dcx().emit_err(errors::CopyPath::new(from, to.as_path(), e));
         }
-        OutFileName::Real(path) => {
-            if let Err(e) = fs::copy(from, path) {
-                sess.dcx().emit_err(errors::CopyPath::new(from, path, e));
-            }
+        OutFileName::Real(path) if let Err(e) = fs::copy(from, path) => {
+            sess.dcx().emit_err(errors::CopyPath::new(from, path, e));
         }
+        _ => {}
     };
 
     let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
@@ -685,14 +682,12 @@ fn produce_final_output_artifacts(
             needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1);
 
         for module in compiled_modules.modules.iter() {
-            if let Some(ref path) = module.object {
-                if !keep_numbered_objects {
+            if !keep_numbered_objects {
+                if let Some(ref path) = module.object {
                     ensure_removed(sess.dcx(), path);
                 }
-            }
 
-            if let Some(ref path) = module.dwarf_object {
-                if !keep_numbered_objects {
+                if let Some(ref path) = module.dwarf_object {
                     ensure_removed(sess.dcx(), path);
                 }
             }
@@ -704,12 +699,11 @@ fn produce_final_output_artifacts(
             }
         }
 
-        if !user_wants_bitcode {
-            if let Some(ref allocator_module) = compiled_modules.allocator_module {
-                if let Some(ref path) = allocator_module.bytecode {
-                    ensure_removed(sess.dcx(), path);
-                }
-            }
+        if !user_wants_bitcode
+            && let Some(ref allocator_module) = compiled_modules.allocator_module
+            && let Some(ref path) = allocator_module.bytecode
+        {
+            ensure_removed(sess.dcx(), path);
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 84703a0a156..18279a4d05f 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -555,11 +555,9 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
 
 pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &mut String) {
     let def_key = tcx.def_key(def_id);
-    if qualified {
-        if let Some(parent) = def_key.parent {
-            push_item_name(tcx, DefId { krate: def_id.krate, index: parent }, true, output);
-            output.push_str("::");
-        }
+    if qualified && let Some(parent) = def_key.parent {
+        push_item_name(tcx, DefId { krate: def_id.krate, index: parent }, true, output);
+        output.push_str("::");
     }
 
     push_unqualified_item_name(tcx, def_id, def_key.disambiguated_data, output);
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 6d1930a402d..d184ce3d61d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -163,25 +163,25 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
         mergeable_succ: bool,
     ) -> MergingSucc {
         let tcx = bx.tcx();
-        if let Some(instance) = instance {
-            if is_call_from_compiler_builtins_to_upstream_monomorphization(tcx, instance) {
-                if destination.is_some() {
-                    let caller_def = fx.instance.def_id();
-                    let e = CompilerBuiltinsCannotCall {
-                        span: tcx.def_span(caller_def),
-                        caller: with_no_trimmed_paths!(tcx.def_path_str(caller_def)),
-                        callee: with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())),
-                    };
-                    tcx.dcx().emit_err(e);
-                } else {
-                    info!(
-                        "compiler_builtins call to diverging function {:?} replaced with abort",
-                        instance.def_id()
-                    );
-                    bx.abort();
-                    bx.unreachable();
-                    return MergingSucc::False;
-                }
+        if let Some(instance) = instance
+            && is_call_from_compiler_builtins_to_upstream_monomorphization(tcx, instance)
+        {
+            if destination.is_some() {
+                let caller_def = fx.instance.def_id();
+                let e = CompilerBuiltinsCannotCall {
+                    span: tcx.def_span(caller_def),
+                    caller: with_no_trimmed_paths!(tcx.def_path_str(caller_def)),
+                    callee: with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())),
+                };
+                tcx.dcx().emit_err(e);
+            } else {
+                info!(
+                    "compiler_builtins call to diverging function {:?} replaced with abort",
+                    instance.def_id()
+                );
+                bx.abort();
+                bx.unreachable();
+                return MergingSucc::False;
             }
         }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 72cfd2bffb5..0fe6a174735 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -837,15 +837,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
         // ZST are passed as operands and require special handling
         // because codegen_place() panics if Local is operand.
-        if let Some(index) = place.as_local() {
-            if let LocalRef::Operand(op) = self.locals[index] {
-                if let ty::Array(_, n) = op.layout.ty.kind() {
-                    let n = n
-                        .try_to_target_usize(bx.tcx())
-                        .expect("expected monomorphic const in codegen");
-                    return bx.cx().const_usize(n);
-                }
-            }
+        if let Some(index) = place.as_local()
+            && let LocalRef::Operand(op) = self.locals[index]
+            && let ty::Array(_, n) = op.layout.ty.kind()
+        {
+            let n = n.try_to_target_usize(bx.tcx()).expect("expected monomorphic const in codegen");
+            return bx.cx().const_usize(n);
         }
         // use common size calculation for non zero-sized types
         let cg_value = self.codegen_place(bx, place.as_ref());
diff --git a/compiler/rustc_error_codes/src/error_codes/E0515.md b/compiler/rustc_error_codes/src/error_codes/E0515.md
index 0f4fbf67223..87bbe4aea70 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0515.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0515.md
@@ -17,10 +17,13 @@ fn get_dangling_iterator<'a>() -> Iter<'a, i32> {
 }
 ```
 
-Local variables, function parameters and temporaries are all dropped before the
-end of the function body. So a reference to them cannot be returned.
+Local variables, function parameters and temporaries are all dropped before
+the end of the function body. A returned reference (or struct containing a
+reference) to such a dropped value would immediately be invalid. Therefore
+it is not allowed to return such a reference.
 
-Consider returning an owned value instead:
+Consider returning a value that takes ownership of local data instead of
+referencing it:
 
 ```
 use std::vec::IntoIter;
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 5cf231d5668..b5857e359a2 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3755,7 +3755,10 @@ pub enum UseKind {
     /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
     /// Also produced for each element of a list `use`, e.g.
     /// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
-    Single,
+    ///
+    /// The identifier is the name defined by the import. E.g. for `use
+    /// foo::bar` it is `bar`, for `use foo::bar as baz` it is `baz`.
+    Single(Ident),
 
     /// Glob import, e.g., `use foo::*`.
     Glob,
@@ -3897,8 +3900,6 @@ impl ItemId {
 
 /// An item
 ///
-/// The name might be a dummy name in case of anonymous items
-///
 /// For more details, see the [rust lang reference].
 /// Note that the reference does not document nightly-only features.
 /// There may be also slight differences in the names and representation of AST nodes between
@@ -3907,7 +3908,6 @@ impl ItemId {
 /// [rust lang reference]: https://doc.rust-lang.org/reference/items.html
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Item<'hir> {
-    pub ident: Ident,
     pub owner_id: OwnerId,
     pub kind: ItemKind<'hir>,
     pub span: Span,
@@ -3937,46 +3937,56 @@ impl<'hir> Item<'hir> {
     }
 
     expect_methods_self_kind! {
-        expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s;
+        expect_extern_crate, (Option<Symbol>, Ident),
+            ItemKind::ExternCrate(s, ident), (*s, *ident);
 
         expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
 
-        expect_static, (&'hir Ty<'hir>, Mutability, BodyId),
-            ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body);
+        expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId),
+            ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body);
 
-        expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
-            ItemKind::Const(ty, generics, body), (ty, generics, *body);
+        expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
+            ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body);
 
-        expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId),
-            ItemKind::Fn { sig, generics, body, .. }, (sig, generics, *body);
+        expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
+            ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
 
-        expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk);
+        expect_macro, (Ident, &ast::MacroDef, MacroKind),
+            ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
 
-        expect_mod, &'hir Mod<'hir>, ItemKind::Mod(m), m;
+        expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
 
         expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
             ItemKind::ForeignMod { abi, items }, (*abi, items);
 
         expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
 
-        expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
-            ItemKind::TyAlias(ty, generics), (ty, generics);
+        expect_ty_alias, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
+            ItemKind::TyAlias(ident, ty, generics), (*ident, ty, generics);
 
-        expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
+        expect_enum, (Ident, &EnumDef<'hir>, &'hir Generics<'hir>),
+            ItemKind::Enum(ident, def, generics), (*ident, def, generics);
 
-        expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
-            ItemKind::Struct(data, generics), (data, generics);
+        expect_struct, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
+            ItemKind::Struct(ident, data, generics), (*ident, data, generics);
 
-        expect_union, (&VariantData<'hir>, &'hir Generics<'hir>),
-            ItemKind::Union(data, generics), (data, generics);
+        expect_union, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
+            ItemKind::Union(ident, data, generics), (*ident, data, generics);
 
         expect_trait,
-            (IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
-            ItemKind::Trait(is_auto, safety, generics, bounds, items),
-            (*is_auto, *safety, generics, bounds, items);
-
-        expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>),
-            ItemKind::TraitAlias(generics, bounds), (generics, bounds);
+            (
+                IsAuto,
+                Safety,
+                Ident,
+                &'hir Generics<'hir>,
+                GenericBounds<'hir>,
+                &'hir [TraitItemRef]
+            ),
+            ItemKind::Trait(is_auto, safety, ident, generics, bounds, items),
+            (*is_auto, *safety, *ident, generics, bounds, items);
+
+        expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
+            ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
 
         expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
     }
@@ -4094,7 +4104,7 @@ pub enum ItemKind<'hir> {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
     /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
-    ExternCrate(Option<Symbol>),
+    ExternCrate(Option<Symbol>, Ident),
 
     /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
     ///
@@ -4104,11 +4114,12 @@ pub enum ItemKind<'hir> {
     Use(&'hir UsePath<'hir>, UseKind),
 
     /// A `static` item.
-    Static(&'hir Ty<'hir>, Mutability, BodyId),
+    Static(Ident, &'hir Ty<'hir>, Mutability, BodyId),
     /// A `const` item.
-    Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
+    Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
     /// A function declaration.
     Fn {
+        ident: Ident,
         sig: FnSig<'hir>,
         generics: &'hir Generics<'hir>,
         body: BodyId,
@@ -4118,9 +4129,9 @@ pub enum ItemKind<'hir> {
         has_body: bool,
     },
     /// A MBE macro definition (`macro_rules!` or `macro`).
-    Macro(&'hir ast::MacroDef, MacroKind),
+    Macro(Ident, &'hir ast::MacroDef, MacroKind),
     /// A module.
-    Mod(&'hir Mod<'hir>),
+    Mod(Ident, &'hir Mod<'hir>),
     /// An external module, e.g. `extern { .. }`.
     ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
     /// Module-level inline assembly (from `global_asm!`).
@@ -4134,17 +4145,17 @@ pub enum ItemKind<'hir> {
         fake_body: BodyId,
     },
     /// A type alias, e.g., `type Foo = Bar<u8>`.
-    TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
-    /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
-    Enum(EnumDef<'hir>, &'hir Generics<'hir>),
+    TyAlias(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
+    /// An enum definition, e.g., `enum Foo<A, B> { C<A>, D<B> }`.
+    Enum(Ident, EnumDef<'hir>, &'hir Generics<'hir>),
     /// A struct definition, e.g., `struct Foo<A> {x: A}`.
-    Struct(VariantData<'hir>, &'hir Generics<'hir>),
+    Struct(Ident, VariantData<'hir>, &'hir Generics<'hir>),
     /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
-    Union(VariantData<'hir>, &'hir Generics<'hir>),
+    Union(Ident, VariantData<'hir>, &'hir Generics<'hir>),
     /// A trait definition.
-    Trait(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
+    Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
     /// A trait alias.
-    TraitAlias(&'hir Generics<'hir>, GenericBounds<'hir>),
+    TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
 
     /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
     Impl(&'hir Impl<'hir>),
@@ -4173,16 +4184,39 @@ pub struct Impl<'hir> {
 }
 
 impl ItemKind<'_> {
+    pub fn ident(&self) -> Option<Ident> {
+        match *self {
+            ItemKind::ExternCrate(_, ident)
+            | ItemKind::Use(_, UseKind::Single(ident))
+            | ItemKind::Static(ident, ..)
+            | ItemKind::Const(ident, ..)
+            | ItemKind::Fn { ident, .. }
+            | ItemKind::Macro(ident, ..)
+            | ItemKind::Mod(ident, ..)
+            | ItemKind::TyAlias(ident, ..)
+            | ItemKind::Enum(ident, ..)
+            | ItemKind::Struct(ident, ..)
+            | ItemKind::Union(ident, ..)
+            | ItemKind::Trait(_, _, ident, ..)
+            | ItemKind::TraitAlias(ident, ..) => Some(ident),
+
+            ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
+            | ItemKind::ForeignMod { .. }
+            | ItemKind::GlobalAsm { .. }
+            | ItemKind::Impl(_) => None,
+        }
+    }
+
     pub fn generics(&self) -> Option<&Generics<'_>> {
         Some(match self {
             ItemKind::Fn { generics, .. }
-            | ItemKind::TyAlias(_, generics)
-            | ItemKind::Const(_, generics, _)
-            | ItemKind::Enum(_, generics)
-            | ItemKind::Struct(_, generics)
-            | ItemKind::Union(_, generics)
-            | ItemKind::Trait(_, _, generics, _, _)
-            | ItemKind::TraitAlias(generics, _)
+            | ItemKind::TyAlias(_, _, generics)
+            | ItemKind::Const(_, _, generics, _)
+            | ItemKind::Enum(_, _, generics)
+            | ItemKind::Struct(_, _, generics)
+            | ItemKind::Union(_, _, generics)
+            | ItemKind::Trait(_, _, _, generics, _, _)
+            | ItemKind::TraitAlias(_, generics, _)
             | ItemKind::Impl(Impl { generics, .. }) => generics,
             _ => return None,
         })
@@ -4374,8 +4408,8 @@ impl<'hir> OwnerNode<'hir> {
         match self {
             OwnerNode::Item(Item {
                 kind:
-                    ItemKind::Static(_, _, body)
-                    | ItemKind::Const(_, _, body)
+                    ItemKind::Static(_, _, _, body)
+                    | ItemKind::Const(_, _, _, body)
                     | ItemKind::Fn { body, .. },
                 ..
             })
@@ -4518,12 +4552,12 @@ impl<'hir> Node<'hir> {
     /// ```
     pub fn ident(&self) -> Option<Ident> {
         match self {
+            Node::Item(item) => item.kind.ident(),
             Node::TraitItem(TraitItem { ident, .. })
             | Node::ImplItem(ImplItem { ident, .. })
             | Node::ForeignItem(ForeignItem { ident, .. })
             | Node::Field(FieldDef { ident, .. })
             | Node::Variant(Variant { ident, .. })
-            | Node::Item(Item { ident, .. })
             | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
             Node::Lifetime(lt) => Some(lt.ident),
             Node::GenericParam(p) => Some(p.name.ident()),
@@ -4599,9 +4633,9 @@ impl<'hir> Node<'hir> {
     pub fn ty(self) -> Option<&'hir Ty<'hir>> {
         match self {
             Node::Item(it) => match it.kind {
-                ItemKind::TyAlias(ty, _)
-                | ItemKind::Static(ty, _, _)
-                | ItemKind::Const(ty, _, _) => Some(ty),
+                ItemKind::TyAlias(_, ty, _)
+                | ItemKind::Static(_, ty, _, _)
+                | ItemKind::Const(_, ty, _, _) => Some(ty),
                 ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
                 _ => None,
             },
@@ -4621,7 +4655,7 @@ impl<'hir> Node<'hir> {
 
     pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
         match self {
-            Node::Item(Item { kind: ItemKind::TyAlias(ty, ..), .. }) => Some(ty),
+            Node::Item(Item { kind: ItemKind::TyAlias(_, ty, _), .. }) => Some(ty),
             _ => None,
         }
     }
@@ -4632,7 +4666,9 @@ impl<'hir> Node<'hir> {
             Node::Item(Item {
                 owner_id,
                 kind:
-                    ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. },
+                    ItemKind::Const(_, _, _, body)
+                    | ItemKind::Static(.., body)
+                    | ItemKind::Fn { body, .. },
                 ..
             })
             | Node::TraitItem(TraitItem {
@@ -4693,8 +4729,8 @@ impl<'hir> Node<'hir> {
     pub fn fn_kind(self) -> Option<FnKind<'hir>> {
         match self {
             Node::Item(i) => match i.kind {
-                ItemKind::Fn { sig, generics, .. } => {
-                    Some(FnKind::ItemFn(i.ident, generics, sig.header))
+                ItemKind::Fn { ident, sig, generics, .. } => {
+                    Some(FnKind::ItemFn(ident, generics, sig.header))
                 }
                 _ => None,
             },
@@ -4767,7 +4803,7 @@ mod size_asserts {
     static_assert_size!(ImplItem<'_>, 88);
     static_assert_size!(ImplItemKind<'_>, 40);
     static_assert_size!(Item<'_>, 88);
-    static_assert_size!(ItemKind<'_>, 56);
+    static_assert_size!(ItemKind<'_>, 64);
     static_assert_size!(LetStmt<'_>, 64);
     static_assert_size!(Param<'_>, 32);
     static_assert_size!(Pat<'_>, 72);
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 3ef645a5f61..b79ae1e7cc2 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -533,34 +533,44 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) ->
 
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result {
     try_visit!(visitor.visit_id(item.hir_id()));
-    try_visit!(visitor.visit_ident(item.ident));
     match item.kind {
-        ItemKind::ExternCrate(orig_name) => {
+        ItemKind::ExternCrate(orig_name, ident) => {
             visit_opt!(visitor, visit_name, orig_name);
+            try_visit!(visitor.visit_ident(ident));
         }
-        ItemKind::Use(ref path, _) => {
+        ItemKind::Use(ref path, kind) => {
             try_visit!(visitor.visit_use(path, item.hir_id()));
+            match kind {
+                UseKind::Single(ident) => try_visit!(visitor.visit_ident(ident)),
+                UseKind::Glob | UseKind::ListStem => {}
+            }
         }
-        ItemKind::Static(ref typ, _, body) => {
+        ItemKind::Static(ident, ref typ, _, body) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_ty_unambig(typ));
             try_visit!(visitor.visit_nested_body(body));
         }
-        ItemKind::Const(ref typ, ref generics, body) => {
+        ItemKind::Const(ident, ref typ, ref generics, body) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_ty_unambig(typ));
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_nested_body(body));
         }
-        ItemKind::Fn { sig, generics, body: body_id, .. } => {
+        ItemKind::Fn { ident, sig, generics, body: body_id, .. } => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_fn(
-                FnKind::ItemFn(item.ident, generics, sig.header),
+                FnKind::ItemFn(ident, generics, sig.header),
                 sig.decl,
                 body_id,
                 item.span,
                 item.owner_id.def_id,
             ));
         }
-        ItemKind::Macro(..) => {}
-        ItemKind::Mod(ref module) => {
+        ItemKind::Macro(ident, _def, _kind) => {
+            try_visit!(visitor.visit_ident(ident));
+        }
+        ItemKind::Mod(ident, ref module) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_mod(module, item.span, item.hir_id()));
         }
         ItemKind::ForeignMod { abi: _, items } => {
@@ -573,11 +583,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
             // typeck results set correctly.
             try_visit!(visitor.visit_nested_body(fake_body));
         }
-        ItemKind::TyAlias(ref ty, ref generics) => {
+        ItemKind::TyAlias(ident, ref ty, ref generics) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_ty_unambig(ty));
             try_visit!(visitor.visit_generics(generics));
         }
-        ItemKind::Enum(ref enum_definition, ref generics) => {
+        ItemKind::Enum(ident, ref enum_definition, ref generics) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_enum_def(enum_definition));
         }
@@ -597,17 +609,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
             try_visit!(visitor.visit_ty_unambig(self_ty));
             walk_list!(visitor, visit_impl_item_ref, *items);
         }
-        ItemKind::Struct(ref struct_definition, ref generics)
-        | ItemKind::Union(ref struct_definition, ref generics) => {
+        ItemKind::Struct(ident, ref struct_definition, ref generics)
+        | ItemKind::Union(ident, ref struct_definition, ref generics) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_variant_data(struct_definition));
         }
-        ItemKind::Trait(.., ref generics, bounds, trait_item_refs) => {
+        ItemKind::Trait(_is_auto, _safety, ident, ref generics, bounds, trait_item_refs) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_generics(generics));
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
         }
-        ItemKind::TraitAlias(ref generics, bounds) => {
+        ItemKind::TraitAlias(ident, ref generics, bounds) => {
+            try_visit!(visitor.visit_ident(ident));
             try_visit!(visitor.visit_generics(generics));
             walk_list!(visitor, visit_param_bound, bounds);
         }
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 4769153ff4d..952af592311 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -269,26 +269,26 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
             }
             res
         }
-        hir::ItemKind::Fn { sig, .. } => {
-            check_item_fn(tcx, def_id, item.ident, item.span, sig.decl)
+        hir::ItemKind::Fn { ident, sig, .. } => {
+            check_item_fn(tcx, def_id, ident, item.span, sig.decl)
         }
-        hir::ItemKind::Static(ty, ..) => {
+        hir::ItemKind::Static(_, ty, ..) => {
             check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
         }
-        hir::ItemKind::Const(ty, ..) => {
+        hir::ItemKind::Const(_, ty, ..) => {
             check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
         }
-        hir::ItemKind::Struct(_, hir_generics) => {
+        hir::ItemKind::Struct(_, _, hir_generics) => {
             let res = check_type_defn(tcx, item, false);
             check_variances_for_type_defn(tcx, item, hir_generics);
             res
         }
-        hir::ItemKind::Union(_, hir_generics) => {
+        hir::ItemKind::Union(_, _, hir_generics) => {
             let res = check_type_defn(tcx, item, true);
             check_variances_for_type_defn(tcx, item, hir_generics);
             res
         }
-        hir::ItemKind::Enum(_, hir_generics) => {
+        hir::ItemKind::Enum(_, _, hir_generics) => {
             let res = check_type_defn(tcx, item, true);
             check_variances_for_type_defn(tcx, item, hir_generics);
             res
@@ -297,7 +297,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
         // `ForeignItem`s are handled separately.
         hir::ItemKind::ForeignMod { .. } => Ok(()),
-        hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => {
+        hir::ItemKind::TyAlias(_, hir_ty, hir_generics)
+            if tcx.type_alias_is_lazy(item.owner_id) =>
+        {
             let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
                 let ty = tcx.type_of(def_id).instantiate_identity();
                 let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
@@ -822,10 +824,10 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
 ///
 /// In such cases, suggest using `Self` instead.
 fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
-    let (trait_name, trait_def_id) =
+    let (trait_ident, trait_def_id) =
         match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) {
             hir::Node::Item(item) => match item.kind {
-                hir::ItemKind::Trait(..) => (item.ident, item.owner_id),
+                hir::ItemKind::Trait(_, _, ident, ..) => (ident, item.owner_id),
                 _ => return,
             },
             _ => return,
@@ -862,7 +864,7 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI
                 trait_should_be_self,
                 "associated item referring to unboxed trait object for its own trait",
             )
-            .with_span_label(trait_name.span, "in this trait")
+            .with_span_label(trait_ident.span, "in this trait")
             .with_multipart_suggestion(
                 "you might have meant to use `Self` to refer to the implementing type",
                 sugg,
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 54a630f5b00..075abc32594 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -247,13 +247,13 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
     item: &'tcx hir::Item<'tcx>,
 ) {
     let (generics, suggest) = match &item.kind {
-        hir::ItemKind::Union(_, generics)
-        | hir::ItemKind::Enum(_, generics)
-        | hir::ItemKind::TraitAlias(generics, _)
-        | hir::ItemKind::Trait(_, _, generics, ..)
+        hir::ItemKind::Union(_, _, generics)
+        | hir::ItemKind::Enum(_, _, generics)
+        | hir::ItemKind::TraitAlias(_, generics, _)
+        | hir::ItemKind::Trait(_, _, _, generics, ..)
         | hir::ItemKind::Impl(hir::Impl { generics, .. })
-        | hir::ItemKind::Struct(_, generics) => (generics, true),
-        hir::ItemKind::TyAlias(_, generics) => (generics, false),
+        | hir::ItemKind::Struct(_, _, generics) => (generics, true),
+        hir::ItemKind::TyAlias(_, _, generics) => (generics, false),
         // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
         _ => return,
     };
@@ -470,9 +470,9 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                         .tcx
                         .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
                     match &item.kind {
-                        hir::ItemKind::Enum(_, generics)
-                        | hir::ItemKind::Struct(_, generics)
-                        | hir::ItemKind::Union(_, generics) => {
+                        hir::ItemKind::Enum(_, _, generics)
+                        | hir::ItemKind::Struct(_, _, generics)
+                        | hir::ItemKind::Union(_, _, generics) => {
                             let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
                             let (lt_sp, sugg) = match generics.params {
                                 [] => (generics.span, format!("<{lt_name}>")),
@@ -667,16 +667,16 @@ fn get_new_lifetime_name<'tcx>(
 #[instrument(level = "debug", skip_all)]
 fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     let it = tcx.hir_item(item_id);
-    debug!(item = %it.ident, id = %it.hir_id());
+    debug!(item = ?it.kind.ident(), id = %it.hir_id());
     let def_id = item_id.owner_id.def_id;
     let icx = ItemCtxt::new(tcx, def_id);
 
     match &it.kind {
         // These don't define types.
-        hir::ItemKind::ExternCrate(_)
+        hir::ItemKind::ExternCrate(..)
         | hir::ItemKind::Use(..)
         | hir::ItemKind::Macro(..)
-        | hir::ItemKind::Mod(_)
+        | hir::ItemKind::Mod(..)
         | hir::ItemKind::GlobalAsm { .. } => {}
         hir::ItemKind::ForeignMod { items, .. } => {
             for item in *items {
@@ -736,7 +736,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
             tcx.at(it.span).explicit_super_predicates_of(def_id);
             tcx.ensure_ok().predicates_of(def_id);
         }
-        hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => {
+        hir::ItemKind::Struct(_, struct_def, _) | hir::ItemKind::Union(_, struct_def, _) => {
             tcx.ensure_ok().generics_of(def_id);
             tcx.ensure_ok().type_of(def_id);
             tcx.ensure_ok().predicates_of(def_id);
@@ -758,7 +758,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
             tcx.ensure_ok().predicates_of(def_id);
         }
 
-        hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => {
+        hir::ItemKind::Static(_, ty, ..) | hir::ItemKind::Const(_, ty, ..) => {
             tcx.ensure_ok().generics_of(def_id);
             tcx.ensure_ok().type_of(def_id);
             tcx.ensure_ok().predicates_of(def_id);
@@ -1089,7 +1089,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
 
     let repr = tcx.repr_options_of_def(def_id);
     let (kind, variants) = match &item.kind {
-        ItemKind::Enum(def, _) => {
+        ItemKind::Enum(_, def, _) => {
             let mut distance_from_explicit = 0;
             let variants = def
                 .variants
@@ -1117,7 +1117,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
 
             (AdtKind::Enum, variants)
         }
-        ItemKind::Struct(def, _) | ItemKind::Union(def, _) => {
+        ItemKind::Struct(ident, def, _) | ItemKind::Union(ident, def, _) => {
             let adt_kind = match item.kind {
                 ItemKind::Struct(..) => AdtKind::Struct,
                 _ => AdtKind::Union,
@@ -1125,7 +1125,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
             let variants = std::iter::once(lower_variant(
                 tcx,
                 None,
-                item.ident,
+                *ident,
                 ty::VariantDiscr::Relative(0),
                 def,
                 adt_kind,
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
index 7cbd31de6ba..c3f965d8456 100644
--- a/compiler/rustc_hir_analysis/src/collect/dump.rs
+++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
@@ -134,7 +134,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
                 };
                 tcx.vtable_entries(trait_ref)
             }
-            hir::ItemKind::TyAlias(_, _) => {
+            hir::ItemKind::TyAlias(..) => {
                 let ty = tcx.type_of(def_id).instantiate_identity();
                 if ty.has_non_region_param() {
                     tcx.dcx().span_err(
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 2022127a15b..4bd89861a9e 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -163,7 +163,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                 }
             }
 
-            ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => {
+            ItemKind::Trait(_, _, _, _, self_bounds, ..)
+            | ItemKind::TraitAlias(_, _, self_bounds) => {
                 is_trait = Some(self_bounds);
             }
             _ => {}
@@ -615,7 +616,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
 
     let (generics, superbounds) = match item.kind {
         hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
-        hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits),
+        hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
         _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
     };
 
@@ -959,7 +960,7 @@ pub(super) fn const_conditions<'tcx>(
         Node::Item(item) => match item.kind {
             hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
             hir::ItemKind::Fn { generics, .. } => (generics, None, false),
-            hir::ItemKind::Trait(_, _, generics, supertraits, _) => {
+            hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => {
                 (generics, Some((item.owner_id.def_id, supertraits)), false)
             }
             _ => bug!("const_conditions called on wrong item: {def_id:?}"),
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 883a1acdb30..9b0d57bd75b 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -617,7 +617,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 });
             }
 
-            hir::ItemKind::ExternCrate(_)
+            hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::Use(..)
             | hir::ItemKind::Macro(..)
             | hir::ItemKind::Mod(..)
@@ -627,13 +627,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 // These sorts of items have no lifetime parameters at all.
                 intravisit::walk_item(self, item);
             }
-            hir::ItemKind::TyAlias(_, generics)
-            | hir::ItemKind::Const(_, generics, _)
-            | hir::ItemKind::Enum(_, generics)
-            | hir::ItemKind::Struct(_, generics)
-            | hir::ItemKind::Union(_, generics)
-            | hir::ItemKind::Trait(_, _, generics, ..)
-            | hir::ItemKind::TraitAlias(generics, ..)
+            hir::ItemKind::TyAlias(_, _, generics)
+            | hir::ItemKind::Const(_, _, generics, _)
+            | hir::ItemKind::Enum(_, _, generics)
+            | hir::ItemKind::Struct(_, _, generics)
+            | hir::ItemKind::Union(_, _, generics)
+            | hir::ItemKind::Trait(_, _, _, generics, ..)
+            | hir::ItemKind::TraitAlias(_, generics, ..)
             | hir::ItemKind::Impl(&hir::Impl { generics, .. }) => {
                 // These kinds of items have only early-bound lifetime parameters.
                 self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item));
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 4e8f5ce3986..afda2c142e2 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -202,35 +202,35 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
         },
 
         Node::Item(item) => match item.kind {
-            ItemKind::Static(ty, .., body_id) => {
+            ItemKind::Static(ident, ty, .., body_id) => {
                 if ty.is_suggestable_infer_ty() {
                     infer_placeholder_type(
                         icx.lowerer(),
                         def_id,
                         body_id,
                         ty.span,
-                        item.ident,
+                        ident,
                         "static variable",
                     )
                 } else {
                     icx.lower_ty(ty)
                 }
             }
-            ItemKind::Const(ty, _, body_id) => {
+            ItemKind::Const(ident, ty, _, body_id) => {
                 if ty.is_suggestable_infer_ty() {
                     infer_placeholder_type(
                         icx.lowerer(),
                         def_id,
                         body_id,
                         ty.span,
-                        item.ident,
+                        ident,
                         "constant",
                     )
                 } else {
                     icx.lower_ty(ty)
                 }
             }
-            ItemKind::TyAlias(self_ty, _) => icx.lower_ty(self_ty),
+            ItemKind::TyAlias(_, self_ty, _) => icx.lower_ty(self_ty),
             ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
                 spans if spans.len() > 0 => {
                     let guar = tcx
@@ -479,5 +479,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) ->
             }
         }
     }
-    HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break()
+    HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().1).is_break()
 }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index be726c042da..55886312284 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -140,14 +140,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let generics = match tcx.hir_node_by_def_id(parent_item) {
             hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Struct(variant, generics), ..
+                kind: hir::ItemKind::Struct(_, variant, generics),
+                ..
             }) => {
                 if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) {
                     return false;
                 }
                 generics
             }
-            hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(def, generics), .. }) => {
+            hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, def, generics), .. }) => {
                 if !def
                     .variants
                     .iter()
@@ -267,7 +268,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             hir::Node::Field(field) => {
                 // Enums can't have unsized fields, fields can only have an unsized tail field.
                 if let hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Struct(variant, _), ..
+                    kind: hir::ItemKind::Struct(_, variant, _), ..
                 }) = tcx.parent_hir_node(field.hir_id)
                     && variant
                         .fields()
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 1f5d69bd1b3..e27a81d4976 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -136,9 +136,9 @@ fn diagnostic_hir_wf_check<'tcx>(
                 ref item => bug!("Unexpected TraitItem {:?}", item),
             },
             hir::Node::Item(item) => match item.kind {
-                hir::ItemKind::TyAlias(ty, _)
-                | hir::ItemKind::Static(ty, _, _)
-                | hir::ItemKind::Const(ty, _, _) => vec![ty],
+                hir::ItemKind::TyAlias(_, ty, _)
+                | hir::ItemKind::Static(_, ty, _, _)
+                | hir::ItemKind::Const(_, ty, _, _) => vec![ty],
                 hir::ItemKind::Impl(impl_) => match &impl_.of_trait {
                     Some(t) => t
                         .path
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 1409310339a..98b81dd3def 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -559,7 +559,7 @@ impl<'a> State<'a> {
         self.print_attrs_as_outer(attrs);
         self.ann.pre(self, AnnNode::Item(item));
         match item.kind {
-            hir::ItemKind::ExternCrate(orig_name) => {
+            hir::ItemKind::ExternCrate(orig_name, ident) => {
                 self.head("extern crate");
                 if let Some(orig_name) = orig_name {
                     self.print_name(orig_name);
@@ -567,7 +567,7 @@ impl<'a> State<'a> {
                     self.word("as");
                     self.space();
                 }
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.word(";");
                 self.end(); // end inner head-block
                 self.end(); // end outer head-block
@@ -577,11 +577,11 @@ impl<'a> State<'a> {
                 self.print_path(path, false);
 
                 match kind {
-                    hir::UseKind::Single => {
-                        if path.segments.last().unwrap().ident != item.ident {
+                    hir::UseKind::Single(ident) => {
+                        if path.segments.last().unwrap().ident != ident {
                             self.space();
                             self.word_space("as");
-                            self.print_ident(item.ident);
+                            self.print_ident(ident);
                         }
                         self.word(";");
                     }
@@ -591,12 +591,12 @@ impl<'a> State<'a> {
                 self.end(); // end inner head-block
                 self.end(); // end outer head-block
             }
-            hir::ItemKind::Static(ty, m, expr) => {
+            hir::ItemKind::Static(ident, ty, m, expr) => {
                 self.head("static");
                 if m.is_mut() {
                     self.word_space("mut");
                 }
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.word_space(":");
                 self.print_type(ty);
                 self.space();
@@ -607,9 +607,9 @@ impl<'a> State<'a> {
                 self.word(";");
                 self.end(); // end the outer cbox
             }
-            hir::ItemKind::Const(ty, generics, expr) => {
+            hir::ItemKind::Const(ident, ty, generics, expr) => {
                 self.head("const");
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.print_generic_params(generics.params);
                 self.word_space(":");
                 self.print_type(ty);
@@ -622,30 +622,23 @@ impl<'a> State<'a> {
                 self.word(";");
                 self.end(); // end the outer cbox
             }
-            hir::ItemKind::Fn { sig, generics, body, .. } => {
+            hir::ItemKind::Fn { ident, sig, generics, body, .. } => {
                 self.head("");
-                self.print_fn(
-                    sig.decl,
-                    sig.header,
-                    Some(item.ident.name),
-                    generics,
-                    &[],
-                    Some(body),
-                );
+                self.print_fn(sig.decl, sig.header, Some(ident.name), generics, &[], Some(body));
                 self.word(" ");
                 self.end(); // need to close a box
                 self.end(); // need to close a box
                 self.ann.nested(self, Nested::Body(body));
             }
-            hir::ItemKind::Macro(macro_def, _) => {
-                self.print_mac_def(macro_def, &item.ident, item.span, |_| {});
+            hir::ItemKind::Macro(ident, macro_def, _) => {
+                self.print_mac_def(macro_def, &ident, item.span, |_| {});
             }
-            hir::ItemKind::Mod(_mod) => {
+            hir::ItemKind::Mod(ident, mod_) => {
                 self.head("mod");
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.nbsp();
                 self.bopen();
-                self.print_mod(_mod, attrs);
+                self.print_mod(mod_, attrs);
                 self.bclose(item.span);
             }
             hir::ItemKind::ForeignMod { abi, items } => {
@@ -663,9 +656,9 @@ impl<'a> State<'a> {
                 self.print_inline_asm(asm);
                 self.end()
             }
-            hir::ItemKind::TyAlias(ty, generics) => {
+            hir::ItemKind::TyAlias(ident, ty, generics) => {
                 self.head("type");
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.print_generic_params(generics.params);
                 self.end(); // end the inner ibox
 
@@ -676,16 +669,16 @@ impl<'a> State<'a> {
                 self.word(";");
                 self.end(); // end the outer ibox
             }
-            hir::ItemKind::Enum(ref enum_definition, params) => {
-                self.print_enum_def(enum_definition, params, item.ident.name, item.span);
+            hir::ItemKind::Enum(ident, ref enum_definition, params) => {
+                self.print_enum_def(enum_definition, params, ident.name, item.span);
             }
-            hir::ItemKind::Struct(ref struct_def, generics) => {
+            hir::ItemKind::Struct(ident, ref struct_def, generics) => {
                 self.head("struct");
-                self.print_struct(struct_def, generics, item.ident.name, item.span, true);
+                self.print_struct(struct_def, generics, ident.name, item.span, true);
             }
-            hir::ItemKind::Union(ref struct_def, generics) => {
+            hir::ItemKind::Union(ident, ref struct_def, generics) => {
                 self.head("union");
-                self.print_struct(struct_def, generics, item.ident.name, item.span, true);
+                self.print_struct(struct_def, generics, ident.name, item.span, true);
             }
             hir::ItemKind::Impl(&hir::Impl {
                 constness,
@@ -733,12 +726,12 @@ impl<'a> State<'a> {
                 }
                 self.bclose(item.span);
             }
-            hir::ItemKind::Trait(is_auto, safety, generics, bounds, trait_items) => {
+            hir::ItemKind::Trait(is_auto, safety, ident, generics, bounds, trait_items) => {
                 self.head("");
                 self.print_is_auto(is_auto);
                 self.print_safety(safety);
                 self.word_nbsp("trait");
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.print_generic_params(generics.params);
                 self.print_bounds(":", bounds);
                 self.print_where_clause(generics);
@@ -749,9 +742,9 @@ impl<'a> State<'a> {
                 }
                 self.bclose(item.span);
             }
-            hir::ItemKind::TraitAlias(generics, bounds) => {
+            hir::ItemKind::TraitAlias(ident, generics, bounds) => {
                 self.head("trait");
-                self.print_ident(item.ident);
+                self.print_ident(ident);
                 self.print_generic_params(generics.params);
                 self.nbsp();
                 self.print_bounds("=", bounds);
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 2a24d626ac3..5e2daa69628 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -713,8 +713,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             for id in self.tcx.hir_free_items() {
                 if let Some(node) = self.tcx.hir_get_if_local(id.owner_id.into())
                     && let hir::Node::Item(item) = node
-                    && let hir::ItemKind::Fn { .. } = item.kind
-                    && item.ident.name == segment.ident.name
+                    && let hir::ItemKind::Fn { ident, .. } = item.kind
+                    && ident.name == segment.ident.name
                 {
                     err.span_label(
                         self.tcx.def_span(id.owner_id),
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 3eef32aa7c1..41bdd0ca43e 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -721,8 +721,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         },
                     )) => {
                         if let Some(hir::Node::Item(hir::Item {
-                            ident,
-                            kind: hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..),
+                            kind:
+                                hir::ItemKind::Static(ident, ty, ..)
+                                | hir::ItemKind::Const(ident, ty, ..),
                             ..
                         })) = self.tcx.hir_get_if_local(*def_id)
                         {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index afbb1adf654..264719ca569 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -904,7 +904,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Assumes given function doesn't have a explicit return type.
     fn can_add_return_type(&self, fn_id: LocalDefId) -> bool {
         match self.tcx.hir_node_by_def_id(fn_id) {
-            Node::Item(&hir::Item { ident, .. }) => {
+            Node::Item(item) => {
+                let (ident, _, _, _) = item.expect_fn();
                 // This is less than ideal, it will not suggest a return type span on any
                 // method called `main`, regardless of whether it is actually the entry point,
                 // but it will still present it as the reason for the expected type.
diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
index 72f8793d783..0037d5ac042 100644
--- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
+++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
@@ -367,20 +367,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .collect();
 
         // Find an identifier with which this trait was imported (note that `_` doesn't count).
-        let any_id = import_items.iter().find_map(|item| {
-            if item.ident.name != kw::Underscore { Some(item.ident) } else { None }
-        });
-        if let Some(any_id) = any_id {
-            if any_id.name == kw::Empty {
-                // Glob import, so just use its name.
-                return None;
-            } else {
-                return Some(format!("{any_id}"));
+        for item in import_items.iter() {
+            let (_, kind) = item.expect_use();
+            match kind {
+                hir::UseKind::Single(ident) => {
+                    if ident.name != kw::Underscore {
+                        return Some(format!("{}", ident.name));
+                    }
+                }
+                hir::UseKind::Glob => return None, // Glob import, so just use its name.
+                hir::UseKind::ListStem => unreachable!(),
             }
         }
 
-        // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick,
-        // so just take the first one.
+        // All that is left is `_`! We need to use the full path. It doesn't matter which one we
+        // pick, so just take the first one.
         match import_items[0].kind {
             ItemKind::Use(path, _) => Some(
                 path.segments
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 943661fbd56..cdfae51583b 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1204,13 +1204,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                     Some(
                         Node::Item(hir::Item {
-                            ident,
-                            kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..),
+                            kind:
+                                hir::ItemKind::Trait(_, _, ident, ..)
+                                | hir::ItemKind::TraitAlias(ident, ..),
                             ..
                         })
                         // We may also encounter unsatisfied GAT or method bounds
                         | Node::TraitItem(hir::TraitItem { ident, .. })
-                        | Node::ImplItem(hir::ImplItem { ident, .. }),
+                        | Node::ImplItem(hir::ImplItem { ident, .. })
                     ) => {
                         skip_list.insert(p);
                         let entry = spanned_predicates.entry(ident.span);
@@ -3960,8 +3961,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             return;
                         }
                         Node::Item(hir::Item {
-                            kind: hir::ItemKind::Trait(.., bounds, _),
-                            ident,
+                            kind: hir::ItemKind::Trait(_, _, ident, _, bounds, _),
                             ..
                         }) => {
                             let (sp, sep, article) = if bounds.is_empty() {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 3d1c61a9c34..56dae2d7d54 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1250,7 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         match opt_def_id {
             Some(def_id) => match self.tcx.hir_get_if_local(def_id) {
                 Some(hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Const(_, _, body_id),
+                    kind: hir::ItemKind::Const(_, _, _, body_id),
                     ..
                 })) => match self.tcx.hir_node(body_id.hir_id) {
                     hir::Node::Expr(expr) => {
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index b4892e73842..9dccd4a0552 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -441,7 +441,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
         // so we will continue to exclude them for compatibility.
         //
         // The documentation on `ExternCrate` is not used at the moment so no need to warn for it.
-        if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(_) =
+        if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(..) =
             it.kind
         {
             return;
@@ -545,21 +545,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
             return;
         }
         let (def, ty) = match item.kind {
-            hir::ItemKind::Struct(_, ast_generics) => {
+            hir::ItemKind::Struct(_, _, ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
                 (def, Ty::new_adt(cx.tcx, def, ty::List::empty()))
             }
-            hir::ItemKind::Union(_, ast_generics) => {
+            hir::ItemKind::Union(_, _, ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
                 (def, Ty::new_adt(cx.tcx, def, ty::List::empty()))
             }
-            hir::ItemKind::Enum(_, ast_generics) => {
+            hir::ItemKind::Enum(_, _, ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
@@ -1416,7 +1416,7 @@ impl TypeAliasBounds {
 
 impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
-        let hir::ItemKind::TyAlias(hir_ty, generics) = item.kind else { return };
+        let hir::ItemKind::TyAlias(_, hir_ty, generics) = item.kind else { return };
 
         // There must not be a where clause.
         if generics.predicates.is_empty() {
@@ -2119,9 +2119,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
         use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
 
         let def_id = item.owner_id.def_id;
-        if let hir::ItemKind::Struct(_, hir_generics)
-        | hir::ItemKind::Enum(_, hir_generics)
-        | hir::ItemKind::Union(_, hir_generics) = item.kind
+        if let hir::ItemKind::Struct(_, _, hir_generics)
+        | hir::ItemKind::Enum(_, _, hir_generics)
+        | hir::ItemKind::Union(_, _, hir_generics) = item.kind
         {
             let inferred_outlives = cx.tcx.inferred_outlives_of(def_id);
             if inferred_outlives.is_empty() {
@@ -2257,7 +2257,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                 // generics, except for tuple struct, which have the `where`
                 // after the fields of the struct.
                 let full_where_span =
-                    if let hir::ItemKind::Struct(hir::VariantData::Tuple(..), _) = item.kind {
+                    if let hir::ItemKind::Struct(_, hir::VariantData::Tuple(..), _) = item.kind {
                         where_span
                     } else {
                         hir_generics.span.shrink_to_hi().to(where_span)
diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs
index 58efca5e994..78d129642dc 100644
--- a/compiler/rustc_lint/src/default_could_be_derived.rs
+++ b/compiler/rustc_lint/src/default_could_be_derived.rs
@@ -93,7 +93,11 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
         let orig_fields = match cx.tcx.hir_get_if_local(type_def_id) {
             Some(hir::Node::Item(hir::Item {
                 kind:
-                    hir::ItemKind::Struct(hir::VariantData::Struct { fields, recovered: _ }, _generics),
+                    hir::ItemKind::Struct(
+                        _,
+                        hir::VariantData::Struct { fields, recovered: _ },
+                        _generics,
+                    ),
                 ..
             })) => fields.iter().map(|f| (f.ident.name, f)).collect::<FxHashMap<_, _>>(),
             _ => return,
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 1f999bbea5f..b359ee790a5 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -308,18 +308,18 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr {
             [.., penultimate, segment]
                 if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
             {
-                (segment.ident.span, item.ident.span, "*")
+                (segment.ident.span, item.kind.ident().unwrap().span, "*")
             }
             [.., segment]
                 if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent)
-                    && let rustc_hir::UseKind::Single = kind =>
+                    && let rustc_hir::UseKind::Single(ident) = kind =>
             {
                 let (lo, snippet) =
                     match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() {
                         Ok("self") => (path.span, "*"),
                         _ => (segment.ident.span.shrink_to_hi(), "::*"),
                     };
-                (lo, if segment.ident == item.ident { lo } else { item.ident.span }, snippet)
+                (lo, if segment.ident == ident { lo } else { ident.span }, snippet)
             }
             _ => return,
         };
diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
index 35db8632625..dea7c8ac708 100644
--- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
+++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
@@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
         let def_id = item.owner_id.to_def_id();
         // NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because
         // the latter will report `where_clause_object_safety` lint.
-        if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind
+        if let hir::ItemKind::Trait(_, _, ident, ..) = item.kind
             && cx.tcx.is_dyn_compatible(def_id)
         {
             let direct_super_traits_iter = cx
@@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
                 cx.emit_span_lint(
                     MULTIPLE_SUPERTRAIT_UPCASTABLE,
                     cx.tcx.def_span(def_id),
-                    crate::lints::MultipleSupertraitUpcastable { ident: item.ident },
+                    crate::lints::MultipleSupertraitUpcastable { ident },
                 );
             }
         }
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 0890890d12c..f8e0a94f9ec 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -181,10 +181,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     && parent_opt_item_name != Some(kw::Underscore)
                     && let Some(parent) = parent.as_local()
                     && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
-                    && let ItemKind::Const(ty, _, _) = item.kind
+                    && let ItemKind::Const(ident, ty, _, _) = item.kind
                     && let TyKind::Tup(&[]) = ty.kind
                 {
-                    Some(item.ident.span)
+                    Some(ident.span)
                 } else {
                     None
                 };
@@ -238,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     },
                 )
             }
-            ItemKind::Macro(_macro, MacroKind::Bang)
+            ItemKind::Macro(_, _macro, MacroKind::Bang)
                 if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
             {
                 cx.emit_span_lint(
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 9e4fdd2b3ce..715e3506ab8 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -415,8 +415,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
     }
 
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
-        if let hir::ItemKind::Mod(_) = it.kind {
-            self.check_snake_case(cx, "module", &it.ident);
+        if let hir::ItemKind::Mod(ident, _) = it.kind {
+            self.check_snake_case(cx, "module", &ident);
         }
     }
 
@@ -498,11 +498,13 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
         let attrs = cx.tcx.hir_attrs(it.hir_id());
         match it.kind {
-            hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
+            hir::ItemKind::Static(ident, ..)
+                if !ast::attr::contains_name(attrs, sym::no_mangle) =>
+            {
+                NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident);
             }
-            hir::ItemKind::Const(..) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident);
+            hir::ItemKind::Const(ident, ..) => {
+                NonUpperCaseGlobals::check_upper_case(cx, "constant", &ident);
             }
             _ => {}
         }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 7be48a769fe..a7186eb48fd 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1664,7 +1664,7 @@ impl ImproperCTypesDefinitions {
             && cx.tcx.sess.target.os == "aix"
             && !adt_def.all_fields().next().is_none()
         {
-            let struct_variant_data = item.expect_struct().0;
+            let struct_variant_data = item.expect_struct().1;
             for (index, ..) in struct_variant_data.fields().iter().enumerate() {
                 // Struct fields (after the first field) are checked for the
                 // power alignment rule, as fields after the first are likely
@@ -1696,9 +1696,9 @@ impl ImproperCTypesDefinitions {
 impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
         match item.kind {
-            hir::ItemKind::Static(ty, ..)
-            | hir::ItemKind::Const(ty, ..)
-            | hir::ItemKind::TyAlias(ty, ..) => {
+            hir::ItemKind::Static(_, ty, ..)
+            | hir::ItemKind::Const(_, ty, ..)
+            | hir::ItemKind::TyAlias(_, ty, ..) => {
                 self.check_ty_maybe_containing_foreign_fnptr(
                     cx,
                     ty,
@@ -1765,7 +1765,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
 
 impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
-        if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind {
+        if let hir::ItemKind::Enum(_, ref enum_definition, _) = it.kind {
             let t = cx.tcx.type_of(it.owner_id).instantiate_identity();
             let ty = cx.tcx.erase_regions(t);
             let Ok(layout) = cx.layout_of(ty) else { return };
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 212107edb4d..7ab3d432bdf 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1835,7 +1835,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_info_for_macro(&mut self, def_id: LocalDefId) {
         let tcx = self.tcx;
 
-        let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() };
+        let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro();
         self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules);
         record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
     }
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index c61c7a4fb02..2e589150d3e 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -385,7 +385,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) {
         let hir_id = HirId::make_owner(module.to_local_def_id());
         match self.hir_owner_node(hir_id.owner) {
-            OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. }) => (m, span, hir_id),
+            OwnerNode::Item(&Item { span, kind: ItemKind::Mod(_, m), .. }) => (m, span, hir_id),
             OwnerNode::Crate(item) => (item, item.spans.inner_span, hir_id),
             node => panic!("not a module: {node:?}"),
         }
@@ -847,7 +847,7 @@ impl<'tcx> TyCtxt<'tcx> {
             // A `Ctor` doesn't have an identifier itself, but its parent
             // struct/variant does. Compare with `hir::Map::span`.
             Node::Ctor(..) => match self.parent_hir_node(id) {
-                Node::Item(item) => Some(item.ident),
+                Node::Item(item) => Some(item.kind.ident().unwrap()),
                 Node::Variant(variant) => Some(variant.ident),
                 _ => unreachable!(),
             },
@@ -894,18 +894,14 @@ impl<'hir> Map<'hir> {
         }
 
         fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) -> Span {
-            if ident.name != kw::Empty {
-                let mut span = until_within(item_span, ident.span);
-                if let Some(g) = generics
-                    && !g.span.is_dummy()
-                    && let Some(g_span) = g.span.find_ancestor_inside(item_span)
-                {
-                    span = span.to(g_span);
-                }
-                span
-            } else {
-                item_span
+            let mut span = until_within(item_span, ident.span);
+            if let Some(g) = generics
+                && !g.span.is_dummy()
+                && let Some(g_span) = g.span.find_ancestor_inside(item_span)
+            {
+                span = span.to(g_span);
             }
+            span
         }
 
         let span = match self.tcx.hir_node(hir_id) {
@@ -936,7 +932,7 @@ impl<'hir> Map<'hir> {
             }) => until_within(*outer_span, generics.where_clause_span),
             // Constants and Statics.
             Node::Item(Item {
-                kind: ItemKind::Const(ty, ..) | ItemKind::Static(ty, ..),
+                kind: ItemKind::Const(_, ty, ..) | ItemKind::Static(_, ty, ..),
                 span: outer_span,
                 ..
             })
@@ -957,7 +953,7 @@ impl<'hir> Map<'hir> {
             }) => until_within(*outer_span, ty.span),
             // With generics and bounds.
             Node::Item(Item {
-                kind: ItemKind::Trait(_, _, generics, bounds, _),
+                kind: ItemKind::Trait(_, _, _, generics, bounds, _),
                 span: outer_span,
                 ..
             })
@@ -977,7 +973,13 @@ impl<'hir> Map<'hir> {
                     // SyntaxContext of the path.
                     path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span)
                 }
-                _ => named_span(item.span, item.ident, item.kind.generics()),
+                _ => {
+                    if let Some(ident) = item.kind.ident() {
+                        named_span(item.span, ident, item.kind.generics())
+                    } else {
+                        item.span
+                    }
+                }
             },
             Node::Variant(variant) => named_span(variant.span, variant.ident, None),
             Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
@@ -1327,7 +1329,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
         self.items.push(item.item_id());
 
         // Items that are modules are handled here instead of in visit_mod.
-        if let ItemKind::Mod(module) = &item.kind {
+        if let ItemKind::Mod(_, module) = &item.kind {
             self.submodules.push(item.owner_id);
             // A module collector does not recurse inside nested modules.
             if self.crate_collector {
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 1056644b813..bbcd509c558 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -28,6 +28,7 @@ use tracing::instrument;
 use crate::middle::region;
 use crate::mir::interpret::AllocId;
 use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
+use crate::thir::visit::for_each_immediate_subpat;
 use crate::ty::adjustment::PointerCoercion;
 use crate::ty::layout::IntegerExt;
 use crate::ty::{
@@ -672,27 +673,7 @@ impl<'tcx> Pat<'tcx> {
             return;
         }
 
-        use PatKind::*;
-        match &self.kind {
-            Wild
-            | Never
-            | Range(..)
-            | Binding { subpattern: None, .. }
-            | Constant { .. }
-            | Error(_) => {}
-            AscribeUserType { subpattern, .. }
-            | Binding { subpattern: Some(subpattern), .. }
-            | Deref { subpattern }
-            | DerefPattern { subpattern, .. }
-            | ExpandedConstant { subpattern, .. } => subpattern.walk_(it),
-            Leaf { subpatterns } | Variant { subpatterns, .. } => {
-                subpatterns.iter().for_each(|field| field.pattern.walk_(it))
-            }
-            Or { pats } => pats.iter().for_each(|p| p.walk_(it)),
-            Array { box prefix, slice, box suffix } | Slice { box prefix, slice, box suffix } => {
-                prefix.iter().chain(slice.as_deref()).chain(suffix.iter()).for_each(|p| p.walk_(it))
-            }
-        }
+        for_each_immediate_subpat(self, |p| p.walk_(it));
     }
 
     /// Whether the pattern has a `PatKind::Error` nested within.
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index d208692f4e7..7d62ab7970d 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -240,36 +240,45 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
     visitor: &mut V,
     pat: &'thir Pat<'tcx>,
 ) {
-    use PatKind::*;
+    for_each_immediate_subpat(pat, |p| visitor.visit_pat(p));
+}
+
+/// Invokes `callback` on each immediate subpattern of `pat`, if any.
+/// A building block for assembling THIR pattern visitors.
+pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
+    pat: &'a Pat<'tcx>,
+    mut callback: impl FnMut(&'a Pat<'tcx>),
+) {
     match &pat.kind {
-        AscribeUserType { subpattern, ascription: _ }
-        | Deref { subpattern }
-        | DerefPattern { subpattern, .. }
-        | Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(subpattern),
-        Binding { .. } | Wild | Never | Error(_) => {}
-        Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
-            for subpattern in subpatterns {
-                visitor.visit_pat(&subpattern.pattern);
+        PatKind::Wild
+        | PatKind::Binding { subpattern: None, .. }
+        | PatKind::Constant { value: _ }
+        | PatKind::Range(_)
+        | PatKind::Never
+        | PatKind::Error(_) => {}
+
+        PatKind::AscribeUserType { subpattern, .. }
+        | PatKind::Binding { subpattern: Some(subpattern), .. }
+        | PatKind::Deref { subpattern }
+        | PatKind::DerefPattern { subpattern, .. }
+        | PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern),
+
+        PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => {
+            for field_pat in subpatterns {
+                callback(&field_pat.pattern);
             }
         }
-        Constant { value: _ } => {}
-        ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern),
-        Range(_) => {}
-        Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
-            for subpattern in prefix.iter() {
-                visitor.visit_pat(subpattern);
-            }
-            if let Some(pat) = slice {
-                visitor.visit_pat(pat);
-            }
-            for subpattern in suffix.iter() {
-                visitor.visit_pat(subpattern);
+
+        PatKind::Slice { prefix, slice, suffix } | PatKind::Array { prefix, slice, suffix } => {
+            for pat in prefix.iter().chain(slice.as_deref()).chain(suffix) {
+                callback(pat);
             }
         }
-        Or { pats } => {
-            for pat in pats.iter() {
-                visitor.visit_pat(pat);
+
+        PatKind::Or { pats } => {
+            for pat in pats {
+                callback(pat);
             }
         }
-    };
+    }
 }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index d200b1437c5..3ef8ecc59e4 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -3406,20 +3406,18 @@ define_print_and_forward_display! {
 }
 
 fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) {
-    // Iterate all local crate items no matter where they are defined.
+    // Iterate all (non-anonymous) local crate items no matter where they are defined.
     for id in tcx.hir_free_items() {
         if matches!(tcx.def_kind(id.owner_id), DefKind::Use) {
             continue;
         }
 
         let item = tcx.hir_item(id);
-        if item.ident.name == kw::Empty {
-            continue;
-        }
+        let Some(ident) = item.kind.ident() else { continue };
 
         let def_id = item.owner_id.to_def_id();
         let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS);
-        collect_fn(&item.ident, ns, def_id);
+        collect_fn(&ident, ns, def_id);
     }
 
     // Now take care of extern crate items.
diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs
index 2909dea98b7..c8b69a6ec62 100644
--- a/compiler/rustc_mir_build/src/builder/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/mod.rs
@@ -563,7 +563,7 @@ fn construct_const<'a, 'tcx>(
     // Figure out what primary body this item has.
     let (span, const_ty_span) = match tcx.hir_node(hir_id) {
         Node::Item(hir::Item {
-            kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _),
+            kind: hir::ItemKind::Static(_, ty, _, _) | hir::ItemKind::Const(_, ty, _, _),
             span,
             ..
         })
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index cbd29ba837e..095d3e75da1 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -1044,7 +1044,6 @@ fn find_fallback_pattern_typo<'tcx>(
             if let DefKind::Use = cx.tcx.def_kind(item.owner_id) {
                 // Look for consts being re-exported.
                 let item = cx.tcx.hir_expect_item(item.owner_id.def_id);
-                let use_name = item.ident.name;
                 let hir::ItemKind::Use(path, _) = item.kind else {
                     continue;
                 };
@@ -1064,8 +1063,9 @@ fn find_fallback_pattern_typo<'tcx>(
                         {
                             // The const is accessible only through the re-export, point at
                             // the `use`.
-                            imported.push(use_name);
-                            imported_spans.push(item.ident.span);
+                            let ident = item.kind.ident().unwrap();
+                            imported.push(ident.name);
+                            imported_spans.push(ident.span);
                         }
                     }
                 }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index fb3df5b43ac..d1917f39c07 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -743,7 +743,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         match target {
             Target::Struct => {
                 if let Some(ItemLike::Item(hir::Item {
-                    kind: hir::ItemKind::Struct(hir::VariantData::Struct { fields, .. }, _),
+                    kind: hir::ItemKind::Struct(_, hir::VariantData::Struct { fields, .. }, _),
                     ..
                 })) = item
                     && !fields.is_empty()
@@ -1019,7 +1019,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             _ => None,
         };
         match item_kind {
-            Some(ItemKind::Mod(module)) => {
+            Some(ItemKind::Mod(_, module)) => {
                 if !module.item_ids.is_empty() {
                     self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
                     return;
@@ -1072,9 +1072,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             return;
         };
         match item.kind {
-            ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics)
+            ItemKind::Enum(_, _, generics) | ItemKind::Struct(_, _, generics)
                 if generics.params.len() != 0 => {}
-            ItemKind::Trait(_, _, generics, _, items)
+            ItemKind::Trait(_, _, _, generics, _, items)
                 if generics.params.len() != 0
                     || items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
             _ => {
@@ -2293,7 +2293,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             }
         } else {
             // special case when `#[macro_export]` is applied to a macro 2.0
-            let (macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
+            let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
             let is_decl_macro = !macro_definition.macro_rules;
 
             if is_decl_macro {
@@ -2624,7 +2624,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         // Historically we've run more checks on non-exported than exported macros,
         // so this lets us continue to run them while maintaining backwards compatibility.
         // In the long run, the checks should be harmonized.
-        if let ItemKind::Macro(macro_def, _) = item.kind {
+        if let ItemKind::Macro(_, macro_def, _) = item.kind {
             let def_id = item.owner_id.to_def_id();
             if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
                 check_non_exported_macro_for_invalid_attrs(self.tcx, item);
@@ -2736,7 +2736,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
 }
 
 fn is_c_like_enum(item: &Item<'_>) -> bool {
-    if let ItemKind::Enum(ref def, _) = item.kind {
+    if let ItemKind::Enum(_, ref def, _) = item.kind {
         for variant in def.variants {
             match variant.data {
                 hir::VariantData::Unit(..) => { /* continue */ }
@@ -2784,7 +2784,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
             .map(|id| tcx.hir_item(id))
             .find(|item| !item.span.is_dummy()) // Skip prelude `use`s
             .map(|item| errors::ItemFollowingInnerAttr {
-                span: item.ident.span,
+                span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span },
                 kind: item.kind.descr(),
             });
         let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel {
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d036cb74a56..f77e1db42d4 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -751,7 +751,7 @@ fn check_item<'tcx>(
     match tcx.def_kind(id.owner_id) {
         DefKind::Enum => {
             let item = tcx.hir_item(id);
-            if let hir::ItemKind::Enum(ref enum_def, _) = item.kind {
+            if let hir::ItemKind::Enum(_, ref enum_def, _) = item.kind {
                 if let Some(comes_from_allow) = allow_dead_code {
                     worklist.extend(
                         enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)),
@@ -806,7 +806,7 @@ fn check_item<'tcx>(
         }
         DefKind::Struct => {
             let item = tcx.hir_item(id);
-            if let hir::ItemKind::Struct(ref variant_data, _) = item.kind
+            if let hir::ItemKind::Struct(_, ref variant_data, _) = item.kind
                 && let Some(ctor_def_id) = variant_data.ctor_def_id()
             {
                 struct_constructors.insert(ctor_def_id, item.owner_id.def_id);
@@ -987,7 +987,7 @@ impl<'tcx> DeadVisitor<'tcx> {
                 && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
                 && let Some(enum_local_id) = enum_did.as_local()
                 && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id)
-                && let ItemKind::Enum(_, _) = item.kind
+                && let ItemKind::Enum(..) = item.kind
             {
                 enum_local_id
             } else {
@@ -1062,7 +1062,7 @@ impl<'tcx> DeadVisitor<'tcx> {
                 let tuple_fields = if let Some(parent_id) = parent_item
                     && let node = tcx.hir_node_by_def_id(parent_id)
                     && let hir::Node::Item(hir::Item {
-                        kind: hir::ItemKind::Struct(hir::VariantData::Tuple(fields, _, _), _),
+                        kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(fields, _, _), _),
                         ..
                     }) = node
                 {
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index b9e413a20c1..321e5729b72 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -204,7 +204,7 @@ impl<'tcx> ReachableContext<'tcx> {
                         }
                     }
 
-                    hir::ItemKind::Const(_, _, init) => {
+                    hir::ItemKind::Const(_, _, _, init) => {
                         // Only things actually ending up in the final constant value are reachable
                         // for codegen. Everything else is only needed during const-eval, so even if
                         // const-eval happens in a downstream crate, all they need is
@@ -232,7 +232,7 @@ impl<'tcx> ReachableContext<'tcx> {
                     // These are normal, nothing reachable about these
                     // inherently and their children are already in the
                     // worklist, as determined by the privacy pass
-                    hir::ItemKind::ExternCrate(_)
+                    hir::ItemKind::ExternCrate(..)
                     | hir::ItemKind::Use(..)
                     | hir::ItemKind::TyAlias(..)
                     | hir::ItemKind::Macro(..)
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index aea4386295f..9e55914f8f2 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -430,7 +430,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                 kind = AnnotationKind::DeprecationProhibited;
                 const_stab_inherit = InheritConstStability::Yes;
             }
-            hir::ItemKind::Struct(ref sd, _) => {
+            hir::ItemKind::Struct(_, ref sd, _) => {
                 if let Some(ctor_def_id) = sd.ctor_def_id() {
                     self.annotate(
                         ctor_def_id,
@@ -773,10 +773,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         match item.kind {
-            hir::ItemKind::ExternCrate(_) => {
+            hir::ItemKind::ExternCrate(_, ident) => {
                 // compiler-generated `extern crate` items have a dummy span.
                 // `std` is still checked for the `restricted-std` feature.
-                if item.span.is_dummy() && item.ident.name != sym::std {
+                if item.span.is_dummy() && ident.name != sym::std {
                     return;
                 }
 
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 6ed7aabcb29..ed00d97c31d 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -574,7 +574,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             // privacy and mark them reachable.
             DefKind::Macro(_) => {
                 let item = self.tcx.hir_expect_item(def_id);
-                if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind {
+                if let hir::ItemKind::Macro(_, MacroDef { macro_rules: false, .. }, _) = item.kind {
                     if vis.is_accessible_from(module, self.tcx) {
                         self.update(def_id, macro_ev, Level::Reachable);
                     }
@@ -598,8 +598,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             DefKind::Struct | DefKind::Union => {
                 // While structs and unions have type privacy, their fields do not.
                 let item = self.tcx.hir_expect_item(def_id);
-                if let hir::ItemKind::Struct(ref struct_def, _)
-                | hir::ItemKind::Union(ref struct_def, _) = item.kind
+                if let hir::ItemKind::Struct(_, ref struct_def, _)
+                | hir::ItemKind::Union(_, ref struct_def, _) = item.kind
                 {
                     for field in struct_def.fields() {
                         let field_vis = self.tcx.local_visibility(field.def_id);
@@ -653,7 +653,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             | hir::ItemKind::GlobalAsm { .. } => {}
             // The interface is empty, and all nested items are processed by `visit_item`.
             hir::ItemKind::Mod(..) => {}
-            hir::ItemKind::Macro(macro_def, _) => {
+            hir::ItemKind::Macro(_, macro_def, _) => {
                 if let Some(item_ev) = item_ev {
                     self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
                 }
@@ -724,7 +724,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Enum(ref def, _) => {
+            hir::ItemKind::Enum(_, ref def, _) => {
                 if let Some(item_ev) = item_ev {
                     self.reach(item.owner_id.def_id, item_ev).generics().predicates();
                 }
@@ -762,7 +762,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
+            hir::ItemKind::Struct(_, ref struct_def, _)
+            | hir::ItemKind::Union(_, ref struct_def, _) => {
                 if let Some(item_ev) = item_ev {
                     self.reach(item.owner_id.def_id, item_ev).generics().predicates();
                     for field in struct_def.fields() {
@@ -866,7 +867,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> {
         self.effective_visibility_diagnostic(item.owner_id.def_id);
 
         match item.kind {
-            hir::ItemKind::Enum(ref def, _) => {
+            hir::ItemKind::Enum(_, ref def, _) => {
                 for variant in def.variants.iter() {
                     self.effective_visibility_diagnostic(variant.def_id);
                     if let Some(ctor_def_id) = variant.data.ctor_def_id() {
@@ -877,7 +878,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
+            hir::ItemKind::Struct(_, ref def, _) | hir::ItemKind::Union(_, ref def, _) => {
                 if let Some(ctor_def_id) = def.ctor_def_id() {
                     self.effective_visibility_diagnostic(ctor_def_id);
                 }
@@ -1636,7 +1637,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
             }
             DefKind::Enum => {
                 let item = tcx.hir_item(id);
-                if let hir::ItemKind::Enum(ref def, _) = item.kind {
+                if let hir::ItemKind::Enum(_, ref def, _) = item.kind {
                     self.check_unnameable(item.owner_id.def_id, effective_vis);
 
                     self.check(item.owner_id.def_id, item_visibility, effective_vis)
@@ -1674,8 +1675,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
             // Subitems of structs and unions have their own publicity.
             DefKind::Struct | DefKind::Union => {
                 let item = tcx.hir_item(id);
-                if let hir::ItemKind::Struct(ref struct_def, _)
-                | hir::ItemKind::Union(ref struct_def, _) = item.kind
+                if let hir::ItemKind::Struct(_, ref struct_def, _)
+                | hir::ItemKind::Union(_, ref struct_def, _) = item.kind
                 {
                     self.check_unnameable(item.owner_id.def_id, effective_vis);
                     self.check(item.owner_id.def_id, item_visibility, effective_vis)
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index a32b42a6fe3..a96caf227f7 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -923,6 +923,28 @@ impl Target {
                     _ => unreachable!(),
                 }
             }
+            "loongarch64" => {
+                // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname`
+                // about what the intended ABI is.
+                match &*self.llvm_abiname {
+                    "ilp32d" | "lp64d" => {
+                        // Requires d (which implies f), incompatible with nothing.
+                        FeatureConstraints { required: &["d"], incompatible: &[] }
+                    }
+                    "ilp32f" | "lp64f" => {
+                        // Requires f, incompatible with nothing.
+                        FeatureConstraints { required: &["f"], incompatible: &[] }
+                    }
+                    "ilp32s" | "lp64s" => {
+                        // The soft-float ABI does not require any features and is also not
+                        // incompatible with any features. Rust targets explicitly specify the
+                        // LLVM ABI names, which allows for enabling hard-float support even on
+                        // soft-float targets, and ensures that the ABI behavior is as expected.
+                        NOTHING
+                    }
+                    _ => unreachable!(),
+                }
+            }
             _ => NOTHING,
         }
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 6510dbbbe9d..40f8af1f691 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -2026,7 +2026,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 }
                 LetVisitor { span }.visit_body(body).break_value()
             }
-            hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }) => {
+            hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(_, ty, _, _), .. }) => {
                 Some(&ty.peel_refs().kind)
             }
             _ => None,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index d673e5672a0..59c93db9c8f 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -338,7 +338,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                                 ..
                             },
                             hir::PathSegment {
-                                ident: assoc_item_name,
+                                ident: assoc_item_ident,
                                 res: Res::Def(_, item_id),
                                 ..
                             },
@@ -368,17 +368,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
                         if let Some(local_def_id) = data.trait_ref.def_id.as_local()
                             && let hir::Node::Item(hir::Item {
-                                ident: trait_name,
-                                kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs),
+                                kind: hir::ItemKind::Trait(_, _, trait_ident, _, _, trait_item_refs),
                                 ..
                             }) = self.tcx.hir_node_by_def_id(local_def_id)
                             && let Some(method_ref) = trait_item_refs
                                 .iter()
-                                .find(|item_ref| item_ref.ident == *assoc_item_name)
+                                .find(|item_ref| item_ref.ident == *assoc_item_ident)
                         {
                             err.span_label(
                                 method_ref.span,
-                                format!("`{trait_name}::{assoc_item_name}` defined here"),
+                                format!("`{trait_ident}::{assoc_item_ident}` defined here"),
                             );
                         }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index 4d87a93be0c..98df09b6f7b 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -419,7 +419,12 @@ pub fn report_dyn_incompatibility<'tcx>(
 ) -> Diag<'tcx> {
     let trait_str = tcx.def_path_str(trait_def_id);
     let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node {
-        hir::Node::Item(item) => Some(item.ident.span),
+        hir::Node::Item(item) => match item.kind {
+            hir::ItemKind::Trait(_, _, ident, ..) | hir::ItemKind::TraitAlias(ident, _, _) => {
+                Some(ident.span)
+            }
+            _ => unreachable!(),
+        },
         _ => None,
     });
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index df95c626b06..393d175ea4c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -267,8 +267,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             let node = self.tcx.hir_node_by_def_id(body_id);
             match node {
                 hir::Node::Item(hir::Item {
-                    ident,
-                    kind: hir::ItemKind::Trait(_, _, generics, bounds, _),
+                    kind: hir::ItemKind::Trait(_, _, ident, generics, bounds, _),
                     ..
                 }) if self_ty == self.tcx.types.self_param => {
                     assert!(param_ty);
@@ -282,7 +281,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         None,
                         projection,
                         trait_pred,
-                        Some((ident, bounds)),
+                        Some((&ident, bounds)),
                     );
                     return;
                 }
@@ -331,7 +330,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 }
                 hir::Node::Item(hir::Item {
                     kind:
-                        hir::ItemKind::Trait(_, _, generics, ..)
+                        hir::ItemKind::Trait(_, _, _, generics, ..)
                         | hir::ItemKind::Impl(hir::Impl { generics, .. }),
                     ..
                 }) if projection.is_some() => {
@@ -352,15 +351,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
                 hir::Node::Item(hir::Item {
                     kind:
-                        hir::ItemKind::Struct(_, generics)
-                        | hir::ItemKind::Enum(_, generics)
-                        | hir::ItemKind::Union(_, generics)
-                        | hir::ItemKind::Trait(_, _, generics, ..)
+                        hir::ItemKind::Struct(_, _, generics)
+                        | hir::ItemKind::Enum(_, _, generics)
+                        | hir::ItemKind::Union(_, _, generics)
+                        | hir::ItemKind::Trait(_, _, _, generics, ..)
                         | hir::ItemKind::Impl(hir::Impl { generics, .. })
                         | hir::ItemKind::Fn { generics, .. }
-                        | hir::ItemKind::TyAlias(_, generics)
-                        | hir::ItemKind::Const(_, generics, _)
-                        | hir::ItemKind::TraitAlias(generics, _),
+                        | hir::ItemKind::TyAlias(_, _, generics)
+                        | hir::ItemKind::Const(_, _, generics, _)
+                        | hir::ItemKind::TraitAlias(_, generics, _),
                     ..
                 })
                 | hir::Node::TraitItem(hir::TraitItem { generics, .. })
@@ -412,15 +411,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
                 hir::Node::Item(hir::Item {
                     kind:
-                        hir::ItemKind::Struct(_, generics)
-                        | hir::ItemKind::Enum(_, generics)
-                        | hir::ItemKind::Union(_, generics)
-                        | hir::ItemKind::Trait(_, _, generics, ..)
+                        hir::ItemKind::Struct(_, _, generics)
+                        | hir::ItemKind::Enum(_, _, generics)
+                        | hir::ItemKind::Union(_, _, generics)
+                        | hir::ItemKind::Trait(_, _, _, generics, ..)
                         | hir::ItemKind::Impl(hir::Impl { generics, .. })
                         | hir::ItemKind::Fn { generics, .. }
-                        | hir::ItemKind::TyAlias(_, generics)
-                        | hir::ItemKind::Const(_, generics, _)
-                        | hir::ItemKind::TraitAlias(generics, _),
+                        | hir::ItemKind::TyAlias(_, _, generics)
+                        | hir::ItemKind::Const(_, _, generics, _)
+                        | hir::ItemKind::TraitAlias(_, generics, _),
                     ..
                 }) if !param_ty => {
                     // Missing generic type parameter bound.
@@ -842,7 +841,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     name.to_string()
                 }
                 Some(hir::Node::Item(hir::Item {
-                    ident, kind: hir::ItemKind::Fn { .. }, ..
+                    kind: hir::ItemKind::Fn { ident, .. }, ..
                 })) => {
                     err.span_label(ident.span, "consider calling this function");
                     ident.to_string()
@@ -1588,20 +1587,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let Some(typeck_results) = &self.typeck_results
                     && let ty = typeck_results.expr_ty_adjusted(base)
                     && let ty::FnDef(def_id, _args) = ty.kind()
-                    && let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) =
-                        self.tcx.hir_get_if_local(*def_id)
+                    && let Some(hir::Node::Item(item)) = self.tcx.hir_get_if_local(*def_id)
                 {
+                    let (ident, _, _, _) = item.expect_fn();
                     let msg = format!("alternatively, consider making `fn {ident}` asynchronous");
-                    if vis_span.is_empty() {
+                    if item.vis_span.is_empty() {
                         err.span_suggestion_verbose(
-                            span.shrink_to_lo(),
+                            item.span.shrink_to_lo(),
                             msg,
                             "async ",
                             Applicability::MaybeIncorrect,
                         );
                     } else {
                         err.span_suggestion_verbose(
-                            vis_span.shrink_to_hi(),
+                            item.vis_span.shrink_to_hi(),
                             msg,
                             " async",
                             Applicability::MaybeIncorrect,
@@ -3303,8 +3302,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 let mut is_auto_trait = false;
                 match tcx.hir_get_if_local(data.impl_or_alias_def_id) {
                     Some(Node::Item(hir::Item {
-                        kind: hir::ItemKind::Trait(is_auto, ..),
-                        ident,
+                        kind: hir::ItemKind::Trait(is_auto, _, ident, ..),
                         ..
                     })) => {
                         // FIXME: we should do something else so that it works even on crate foreign
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index fe859eb53cd..7159397c4b1 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -516,7 +516,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
                     match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope))
                     {
                         hir::Node::Item(hir::Item {
-                            kind: hir::ItemKind::Trait(_, _, generics, ..),
+                            kind: hir::ItemKind::Trait(_, _, _, generics, ..),
                             ..
                         })
                         | hir::Node::Item(hir::Item {