about summary refs log tree commit diff
path: root/compiler/rustc_hir
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir')
-rw-r--r--compiler/rustc_hir/Cargo.toml3
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs74
-rw-r--r--compiler/rustc_hir/src/attrs/encode_cross_crate.rs5
-rw-r--r--compiler/rustc_hir/src/def.rs73
-rw-r--r--compiler/rustc_hir/src/hir.rs69
-rw-r--r--compiler/rustc_hir/src/hir_id.rs173
-rw-r--r--compiler/rustc_hir/src/intravisit.rs26
-rw-r--r--compiler/rustc_hir/src/lang_items.rs4
-rw-r--r--compiler/rustc_hir/src/lib.rs6
-rw-r--r--compiler/rustc_hir/src/lints.rs3
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs21
-rw-r--r--compiler/rustc_hir/src/target.rs154
-rw-r--r--compiler/rustc_hir/src/version.rs8
13 files changed, 364 insertions, 255 deletions
diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml
index 539d2e6f0b1..1008a3e787d 100644
--- a/compiler/rustc_hir/Cargo.toml
+++ b/compiler/rustc_hir/Cargo.toml
@@ -5,13 +5,16 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
+bitflags = "2.9.1"
 odht = { version = "0.3.1", features = ["nightly"] }
 rustc_abi = { path = "../rustc_abi" }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_error_messages = { path = "../rustc_error_messages" }
 rustc_hashes = { path = "../rustc_hashes" }
+rustc_hir_id = { path = "../rustc_hir_id" }
 rustc_index = { path = "../rustc_index" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index 5f419315467..2209b18df3f 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -1,7 +1,11 @@
+use std::borrow::Cow;
+use std::path::PathBuf;
+
 pub use ReprAttr::*;
 use rustc_abi::Align;
 use rustc_ast::token::CommentKind;
 use rustc_ast::{AttrStyle, ast};
+use rustc_error_messages::{DiagArgValue, IntoDiagArg};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
 use rustc_span::def_id::DefId;
 use rustc_span::hygiene::Transparency;
@@ -187,6 +191,62 @@ pub enum CfgEntry {
     Version(Option<RustcVersion>, Span),
 }
 
+/// Possible values for the `#[linkage]` attribute, allowing to specify the
+/// linkage type for a `MonoItem`.
+///
+/// See <https://llvm.org/docs/LangRef.html#linkage-types> for more details about these variants.
+#[derive(Encodable, Decodable, Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[derive(HashStable_Generic, PrintAttribute)]
+pub enum Linkage {
+    AvailableExternally,
+    Common,
+    ExternalWeak,
+    External,
+    Internal,
+    LinkOnceAny,
+    LinkOnceODR,
+    WeakAny,
+    WeakODR,
+}
+
+#[derive(Clone, Copy, Decodable, Debug, Encodable, PartialEq)]
+#[derive(HashStable_Generic, PrintAttribute)]
+pub enum MirDialect {
+    Analysis,
+    Built,
+    Runtime,
+}
+
+impl IntoDiagArg for MirDialect {
+    fn into_diag_arg(self, _path: &mut Option<PathBuf>) -> DiagArgValue {
+        let arg = match self {
+            MirDialect::Analysis => "analysis",
+            MirDialect::Built => "built",
+            MirDialect::Runtime => "runtime",
+        };
+        DiagArgValue::Str(Cow::Borrowed(arg))
+    }
+}
+
+#[derive(Clone, Copy, Decodable, Debug, Encodable, PartialEq)]
+#[derive(HashStable_Generic, PrintAttribute)]
+pub enum MirPhase {
+    Initial,
+    PostCleanup,
+    Optimized,
+}
+
+impl IntoDiagArg for MirPhase {
+    fn into_diag_arg(self, _path: &mut Option<PathBuf>) -> DiagArgValue {
+        let arg = match self {
+            MirPhase::Initial => "initial",
+            MirPhase::PostCleanup => "post-cleanup",
+            MirPhase::Optimized => "optimized",
+        };
+        DiagArgValue::Str(Cow::Borrowed(arg))
+    }
+}
+
 /// Represents parsed *built-in* inert attributes.
 ///
 /// ## Overview
@@ -249,6 +309,9 @@ pub enum AttributeKind {
     /// Represents `#[rustc_allow_incoherent_impl]`.
     AllowIncoherentImpl(Span),
 
+    /// Represents `#[allow_internal_unsafe]`.
+    AllowInternalUnsafe(Span),
+
     /// Represents `#[allow_internal_unstable]`.
     AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span),
 
@@ -303,6 +366,9 @@ pub enum AttributeKind {
     /// Represents `#[coverage(..)]`.
     Coverage(Span, CoverageAttrKind),
 
+    /// Represents `#[custom_mir]`.
+    CustomMir(Option<(MirDialect, Span)>, Option<(MirPhase, Span)>, Span),
+
     ///Represents `#[rustc_deny_explicit_impl]`.
     DenyExplicitImpl(Span),
 
@@ -357,6 +423,9 @@ pub enum AttributeKind {
     /// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
     LinkSection { name: Symbol, span: Span },
 
+    /// Represents `#[linkage]`.
+    Linkage(Linkage, Span),
+
     /// Represents `#[loop_match]`.
     LoopMatch(Span),
 
@@ -455,8 +524,9 @@ pub enum AttributeKind {
     /// Represents `#[rustc_std_internal_symbol]`.
     StdInternalSymbol(Span),
 
-    /// Represents `#[target_feature(enable = "...")]`
-    TargetFeature(ThinVec<(Symbol, Span)>, Span),
+    /// Represents `#[target_feature(enable = "...")]` and
+    /// `#[unsafe(force_target_feature(enable = "...")]`.
+    TargetFeature { features: ThinVec<(Symbol, Span)>, attr_span: Span, was_forced: bool },
 
     /// Represents `#[track_caller]`
     TrackCaller(Span),
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index e3a7f0b97a8..485ded3981f 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -16,6 +16,7 @@ impl AttributeKind {
             Align { .. } => No,
             AllowConstFnUnstable(..) => No,
             AllowIncoherentImpl(..) => No,
+            AllowInternalUnsafe(..) => Yes,
             AllowInternalUnstable(..) => Yes,
             AsPtr(..) => Yes,
             AutomaticallyDerived(..) => Yes,
@@ -30,6 +31,7 @@ impl AttributeKind {
             ConstTrait(..) => No,
             Coroutine(..) => No,
             Coverage(..) => No,
+            CustomMir(_, _, _) => Yes,
             DenyExplicitImpl(..) => No,
             Deprecation { .. } => Yes,
             DoNotImplementViaObject(..) => No,
@@ -45,6 +47,7 @@ impl AttributeKind {
             LinkName { .. } => Yes, // Needed for rustdoc
             LinkOrdinal { .. } => No,
             LinkSection { .. } => Yes, // Needed for rustdoc
+            Linkage(..) => No,
             LoopMatch(..) => No,
             MacroEscape(..) => No,
             MacroTransparency(..) => Yes,
@@ -75,7 +78,7 @@ impl AttributeKind {
             SpecializationTrait(..) => No,
             Stability { .. } => Yes,
             StdInternalSymbol(..) => No,
-            TargetFeature(..) => No,
+            TargetFeature { .. } => No,
             TrackCaller(..) => Yes,
             TypeConst(..) => Yes,
             UnsafeSpecializationMarker(..) => No,
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 339d4e2eab7..8af4740f376 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -1,10 +1,12 @@
 use std::array::IntoIter;
+use std::borrow::Cow;
 use std::fmt::Debug;
 
 use rustc_ast as ast;
 use rustc_ast::NodeId;
 use rustc_data_structures::stable_hasher::ToStableHashKey;
 use rustc_data_structures::unord::UnordMap;
+use rustc_error_messages::{DiagArgValue, IntoDiagArg};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::Symbol;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -31,6 +33,53 @@ pub enum CtorKind {
     Const,
 }
 
+/// A set of macro kinds, for macros that can have more than one kind
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
+#[derive(HashStable_Generic)]
+pub struct MacroKinds(u8);
+bitflags::bitflags! {
+    impl MacroKinds: u8 {
+        const BANG = 1 << 0;
+        const ATTR = 1 << 1;
+        const DERIVE = 1 << 2;
+    }
+}
+
+impl From<MacroKind> for MacroKinds {
+    fn from(kind: MacroKind) -> Self {
+        match kind {
+            MacroKind::Bang => Self::BANG,
+            MacroKind::Attr => Self::ATTR,
+            MacroKind::Derive => Self::DERIVE,
+        }
+    }
+}
+
+impl MacroKinds {
+    /// Convert the MacroKinds to a static string.
+    ///
+    /// This hardcodes all the possibilities, in order to return a static string.
+    pub fn descr(self) -> &'static str {
+        match self {
+            // FIXME: change this to "function-like macro" and fix all tests
+            Self::BANG => "macro",
+            Self::ATTR => "attribute macro",
+            Self::DERIVE => "derive macro",
+            _ if self == (Self::ATTR | Self::BANG) => "attribute/function macro",
+            _ if self == (Self::DERIVE | Self::BANG) => "derive/function macro",
+            _ if self == (Self::ATTR | Self::DERIVE) => "attribute/derive macro",
+            _ if self.is_all() => "attribute/derive/function macro",
+            _ if self.is_empty() => "useless macro",
+            _ => unreachable!(),
+        }
+    }
+
+    /// Return an indefinite article (a/an) for use with `descr()`
+    pub fn article(self) -> &'static str {
+        if self.contains(Self::ATTR) { "an" } else { "a" }
+    }
+}
+
 /// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
 pub enum NonMacroAttrKind {
@@ -101,7 +150,7 @@ pub enum DefKind {
     AssocConst,
 
     // Macro namespace
-    Macro(MacroKind),
+    Macro(MacroKinds),
 
     // Not namespaced (or they are, but we don't treat them so)
     ExternCrate,
@@ -177,7 +226,7 @@ impl DefKind {
             DefKind::AssocConst => "associated constant",
             DefKind::TyParam => "type parameter",
             DefKind::ConstParam => "const parameter",
-            DefKind::Macro(macro_kind) => macro_kind.descr(),
+            DefKind::Macro(kinds) => kinds.descr(),
             DefKind::LifetimeParam => "lifetime parameter",
             DefKind::Use => "import",
             DefKind::ForeignMod => "foreign module",
@@ -208,7 +257,7 @@ impl DefKind {
             | DefKind::Use
             | DefKind::InlineConst
             | DefKind::ExternCrate => "an",
-            DefKind::Macro(macro_kind) => macro_kind.article(),
+            DefKind::Macro(kinds) => kinds.article(),
             _ => "a",
         }
     }
@@ -539,6 +588,12 @@ pub enum Res<Id = hir::HirId> {
     Err,
 }
 
+impl<Id> IntoDiagArg for Res<Id> {
+    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
+        DiagArgValue::Str(Cow::Borrowed(self.descr()))
+    }
+}
+
 /// The result of resolving a path before lowering to HIR,
 /// with "module" segments resolved and associated item
 /// segments deferred to type checking.
@@ -626,6 +681,12 @@ impl Namespace {
     }
 }
 
+impl IntoDiagArg for Namespace {
+    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
+        DiagArgValue::Str(Cow::Borrowed(self.descr()))
+    }
+}
+
 impl<CTX: crate::HashStableContext> ToStableHashKey<CTX> for Namespace {
     type KeyType = Namespace;
 
@@ -845,10 +906,10 @@ impl<Id> Res<Id> {
         )
     }
 
-    pub fn macro_kind(self) -> Option<MacroKind> {
+    pub fn macro_kinds(self) -> Option<MacroKinds> {
         match self {
-            Res::Def(DefKind::Macro(kind), _) => Some(kind),
-            Res::NonMacroAttr(..) => Some(MacroKind::Attr),
+            Res::Def(DefKind::Macro(kinds), _) => Some(kinds),
+            Res::NonMacroAttr(..) => Some(MacroKinds::ATTR),
             _ => None,
         }
     }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 34db6f92d92..e397c286de2 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-filelength
+use std::borrow::Cow;
 use std::fmt;
 
 use rustc_abi::ExternAbi;
@@ -17,10 +18,10 @@ pub use rustc_ast::{
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::tagged_ptr::TaggedRef;
+use rustc_error_messages::{DiagArgValue, IntoDiagArg};
 use rustc_index::IndexVec;
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::Spanned;
 use rustc_span::{BytePos, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
 use rustc_target::asm::InlineAsmRegOrRegClass;
@@ -30,7 +31,7 @@ use tracing::debug;
 
 use crate::LangItem;
 use crate::attrs::AttributeKind;
-use crate::def::{CtorKind, DefKind, PerNS, Res};
+use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res};
 use crate::def_id::{DefId, LocalDefIdMap};
 pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
 use crate::intravisit::{FnKind, VisitorExt};
@@ -1160,6 +1161,12 @@ pub struct AttrPath {
     pub span: Span,
 }
 
+impl IntoDiagArg for AttrPath {
+    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
+        self.to_string().into_diag_arg(path)
+    }
+}
+
 impl AttrPath {
     pub fn from_ast(path: &ast::Path) -> Self {
         AttrPath {
@@ -1233,6 +1240,13 @@ impl Attribute {
             _ => None,
         }
     }
+
+    pub fn is_parsed_attr(&self) -> bool {
+        match self {
+            Attribute::Parsed(_) => true,
+            Attribute::Unparsed(_) => false,
+        }
+    }
 }
 
 impl AttributeExt for Attribute {
@@ -1303,13 +1317,10 @@ impl AttributeExt for Attribute {
         match &self {
             Attribute::Unparsed(u) => u.span,
             // FIXME: should not be needed anymore when all attrs are parsed
-            Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
             Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::MacroUse { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
-            Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::ShouldPanic { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span,
+            Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
+            Attribute::Parsed(AttributeKind::AllowInternalUnsafe(span)) => *span,
+            Attribute::Parsed(AttributeKind::Linkage(_, span)) => *span,
             a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
         }
     }
@@ -2256,8 +2267,15 @@ impl fmt::Display for ConstContext {
     }
 }
 
-// NOTE: `IntoDiagArg` impl for `ConstContext` lives in `rustc_errors`
-// due to a cyclical dependency between hir and that crate.
+impl IntoDiagArg for ConstContext {
+    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
+        DiagArgValue::Str(Cow::Borrowed(match self {
+            ConstContext::ConstFn => "const_fn",
+            ConstContext::Static(_) => "static",
+            ConstContext::Const { .. } => "const",
+        }))
+    }
+}
 
 /// A literal.
 pub type Lit = Spanned<LitKind>;
@@ -4156,7 +4174,7 @@ impl<'hir> Item<'hir> {
         expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
             ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
 
-        expect_macro, (Ident, &ast::MacroDef, MacroKind),
+        expect_macro, (Ident, &ast::MacroDef, MacroKinds),
             ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
 
         expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
@@ -4194,7 +4212,7 @@ impl<'hir> Item<'hir> {
         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;
+        expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
     }
 }
 
@@ -4335,7 +4353,7 @@ pub enum ItemKind<'hir> {
         has_body: bool,
     },
     /// A MBE macro definition (`macro_rules!` or `macro`).
-    Macro(Ident, &'hir ast::MacroDef, MacroKind),
+    Macro(Ident, &'hir ast::MacroDef, MacroKinds),
     /// A module.
     Mod(Ident, &'hir Mod<'hir>),
     /// An external module, e.g. `extern { .. }`.
@@ -4372,7 +4390,7 @@ pub enum ItemKind<'hir> {
     TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
 
     /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
-    Impl(&'hir Impl<'hir>),
+    Impl(Impl<'hir>),
 }
 
 /// Represents an impl block declaration.
@@ -4381,6 +4399,14 @@ pub enum ItemKind<'hir> {
 /// Refer to [`ImplItem`] for an associated item within an impl block.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Impl<'hir> {
+    pub generics: &'hir Generics<'hir>,
+    pub of_trait: Option<&'hir TraitImplHeader<'hir>>,
+    pub self_ty: &'hir Ty<'hir>,
+    pub items: &'hir [ImplItemId],
+}
+
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub struct TraitImplHeader<'hir> {
     pub constness: Constness,
     pub safety: Safety,
     pub polarity: ImplPolarity,
@@ -4388,13 +4414,7 @@ pub struct Impl<'hir> {
     // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
     // decoding as `Span`s cannot be decoded when a `Session` is not available.
     pub defaultness_span: Option<Span>,
-    pub generics: &'hir Generics<'hir>,
-
-    /// The trait being implemented, if any.
-    pub of_trait: Option<TraitRef<'hir>>,
-
-    pub self_ty: &'hir Ty<'hir>,
-    pub items: &'hir [ImplItemId],
+    pub trait_ref: TraitRef<'hir>,
 }
 
 impl ItemKind<'_> {
@@ -4756,8 +4776,8 @@ impl<'hir> Node<'hir> {
     /// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`.
     pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
         if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
-            && let Some(trait_ref) = impl_block.of_trait
-            && let Some(trait_id) = trait_ref.trait_def_id()
+            && let Some(of_trait) = impl_block.of_trait
+            && let Some(trait_id) = of_trait.trait_ref.trait_def_id()
             && trait_id == trait_def_id
         {
             Some(impl_block)
@@ -4952,7 +4972,7 @@ mod size_asserts {
     static_assert_size!(GenericArg<'_>, 16);
     static_assert_size!(GenericBound<'_>, 64);
     static_assert_size!(Generics<'_>, 56);
-    static_assert_size!(Impl<'_>, 80);
+    static_assert_size!(Impl<'_>, 40);
     static_assert_size!(ImplItem<'_>, 96);
     static_assert_size!(ImplItemKind<'_>, 40);
     static_assert_size!(Item<'_>, 88);
@@ -4967,6 +4987,7 @@ mod size_asserts {
     static_assert_size!(Res, 12);
     static_assert_size!(Stmt<'_>, 32);
     static_assert_size!(StmtKind<'_>, 16);
+    static_assert_size!(TraitImplHeader<'_>, 48);
     static_assert_size!(TraitItem<'_>, 88);
     static_assert_size!(TraitItemKind<'_>, 48);
     static_assert_size!(Ty<'_>, 48);
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
deleted file mode 100644
index b48a081d371..00000000000
--- a/compiler/rustc_hir/src/hir_id.rs
+++ /dev/null
@@ -1,173 +0,0 @@
-use std::fmt::{self, Debug};
-
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
-use rustc_macros::{Decodable, Encodable, HashStable_Generic};
-use rustc_span::HashStableContext;
-use rustc_span::def_id::DefPathHash;
-
-use crate::def_id::{CRATE_DEF_ID, DefId, DefIndex, LocalDefId};
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
-pub struct OwnerId {
-    pub def_id: LocalDefId,
-}
-
-impl Debug for OwnerId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Example: DefId(0:1 ~ aa[7697]::{use#0})
-        Debug::fmt(&self.def_id, f)
-    }
-}
-
-impl From<OwnerId> for HirId {
-    fn from(owner: OwnerId) -> HirId {
-        HirId { owner, local_id: ItemLocalId::ZERO }
-    }
-}
-
-impl From<OwnerId> for DefId {
-    fn from(value: OwnerId) -> Self {
-        value.to_def_id()
-    }
-}
-
-impl OwnerId {
-    #[inline]
-    pub fn to_def_id(self) -> DefId {
-        self.def_id.to_def_id()
-    }
-}
-
-impl rustc_index::Idx for OwnerId {
-    #[inline]
-    fn new(idx: usize) -> Self {
-        OwnerId { def_id: LocalDefId { local_def_index: DefIndex::from_usize(idx) } }
-    }
-
-    #[inline]
-    fn index(self) -> usize {
-        self.def_id.local_def_index.as_usize()
-    }
-}
-
-impl<CTX: HashStableContext> HashStable<CTX> for OwnerId {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
-    }
-}
-
-impl<CTX: HashStableContext> ToStableHashKey<CTX> for OwnerId {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
-        hcx.def_path_hash(self.to_def_id())
-    }
-}
-
-/// Uniquely identifies a node in the HIR of the current crate. It is
-/// composed of the `owner`, which is the `LocalDefId` of the directly enclosing
-/// `hir::Item`, `hir::TraitItem`, or `hir::ImplItem` (i.e., the closest "item-like"),
-/// and the `local_id` which is unique within the given owner.
-///
-/// This two-level structure makes for more stable values: One can move an item
-/// around within the source code, or add or remove stuff before it, without
-/// the `local_id` part of the `HirId` changing, which is a very useful property in
-/// incremental compilation where we have to persist things through changes to
-/// the code base.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
-#[rustc_pass_by_value]
-pub struct HirId {
-    pub owner: OwnerId,
-    pub local_id: ItemLocalId,
-}
-
-// To ensure correctness of incremental compilation,
-// `HirId` must not implement `Ord` or `PartialOrd`.
-// See https://github.com/rust-lang/rust/issues/90317.
-impl !Ord for HirId {}
-impl !PartialOrd for HirId {}
-
-impl Debug for HirId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Example: HirId(DefId(0:1 ~ aa[7697]::{use#0}).10)
-        // Don't use debug_tuple to always keep this on one line.
-        write!(f, "HirId({:?}.{:?})", self.owner, self.local_id)
-    }
-}
-
-impl HirId {
-    /// Signal local id which should never be used.
-    pub const INVALID: HirId =
-        HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::INVALID };
-
-    #[inline]
-    pub fn expect_owner(self) -> OwnerId {
-        assert_eq!(self.local_id.index(), 0);
-        self.owner
-    }
-
-    #[inline]
-    pub fn as_owner(self) -> Option<OwnerId> {
-        if self.local_id.index() == 0 { Some(self.owner) } else { None }
-    }
-
-    #[inline]
-    pub fn is_owner(self) -> bool {
-        self.local_id.index() == 0
-    }
-
-    #[inline]
-    pub fn make_owner(owner: LocalDefId) -> Self {
-        Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO }
-    }
-}
-
-impl fmt::Display for HirId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{self:?}")
-    }
-}
-
-rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
-rustc_data_structures::define_id_collections!(
-    ItemLocalMap,
-    ItemLocalSet,
-    ItemLocalMapEntry,
-    ItemLocalId
-);
-
-rustc_index::newtype_index! {
-    /// An `ItemLocalId` uniquely identifies something within a given "item-like";
-    /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no
-    /// guarantee that the numerical value of a given `ItemLocalId` corresponds to
-    /// the node's position within the owning item in any way, but there is a
-    /// guarantee that the `ItemLocalId`s within an owner occupy a dense range of
-    /// integers starting at zero, so a mapping that maps all or most nodes within
-    /// an "item-like" to something else can be implemented by a `Vec` instead of a
-    /// tree or hash map.
-    #[derive(HashStable_Generic)]
-    #[encodable]
-    #[orderable]
-    pub struct ItemLocalId {}
-}
-
-impl ItemLocalId {
-    /// Signal local id which should never be used.
-    pub const INVALID: ItemLocalId = ItemLocalId::MAX;
-}
-
-impl StableOrd for ItemLocalId {
-    const CAN_USE_UNSTABLE_SORT: bool = true;
-
-    // `Ord` is implemented as just comparing the ItemLocalId's numerical
-    // values and these are not changed by (de-)serialization.
-    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
-}
-
-/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
-pub const CRATE_HIR_ID: HirId =
-    HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::ZERO };
-
-pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID };
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 23fa466859a..9b2f8ae75fa 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -590,21 +590,21 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_enum_def(enum_definition));
         }
-        ItemKind::Impl(Impl {
-            constness: _,
-            safety: _,
-            defaultness: _,
-            polarity: _,
-            defaultness_span: _,
-            generics,
-            of_trait,
-            self_ty,
-            items,
-        }) => {
+        ItemKind::Impl(Impl { generics, of_trait, self_ty, items }) => {
             try_visit!(visitor.visit_generics(generics));
-            visit_opt!(visitor, visit_trait_ref, of_trait);
+            if let Some(TraitImplHeader {
+                constness: _,
+                safety: _,
+                polarity: _,
+                defaultness: _,
+                defaultness_span: _,
+                trait_ref,
+            }) = of_trait
+            {
+                try_visit!(visitor.visit_trait_ref(trait_ref));
+            }
             try_visit!(visitor.visit_ty_unambig(self_ty));
-            walk_list!(visitor, visit_impl_item_ref, *items);
+            walk_list!(visitor, visit_impl_item_ref, items);
         }
         ItemKind::Struct(ident, ref generics, ref struct_definition)
         | ItemKind::Union(ident, ref generics, ref struct_definition) => {
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 75c04b23ed6..0464665b41f 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -286,6 +286,7 @@ language_item_table! {
     Panic,                   sym::panic,               panic_fn,                   Target::Fn,             GenericRequirement::Exact(0);
     PanicNounwind,           sym::panic_nounwind,      panic_nounwind,             Target::Fn,             GenericRequirement::Exact(0);
     PanicFmt,                sym::panic_fmt,           panic_fmt,                  Target::Fn,             GenericRequirement::None;
+    PanicDisplay,            sym::panic_display,       panic_display,              Target::Fn,             GenericRequirement::None;
     ConstPanicFmt,           sym::const_panic_fmt,     const_panic_fmt,            Target::Fn,             GenericRequirement::None;
     PanicBoundsCheck,        sym::panic_bounds_check,  panic_bounds_check_fn,      Target::Fn,             GenericRequirement::Exact(0);
     PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0);
@@ -436,6 +437,9 @@ language_item_table! {
     DefaultTrait1,           sym::default_trait1,      default_trait1_trait,       Target::Trait,          GenericRequirement::None;
 
     ContractCheckEnsures,     sym::contract_check_ensures,      contract_check_ensures_fn,      Target::Fn, GenericRequirement::None;
+
+    // Reborrowing related lang-items
+    Reborrow,                sym::reborrow,            reborrow,                   Target::Trait,          GenericRequirement::Exact(0);
 }
 
 /// The requirement imposed on the generics of a lang item
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index f1212d07ff6..78fc63753a2 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -3,14 +3,11 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
 
 // tidy-alphabetical-start
-#![allow(internal_features)]
 #![feature(associated_type_defaults)]
 #![feature(closure_track_caller)]
 #![feature(debug_closure_helpers)]
 #![feature(exhaustive_patterns)]
-#![feature(negative_impls)]
 #![feature(never_type)]
-#![feature(rustc_attrs)]
 #![feature(variant_count)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
@@ -25,7 +22,7 @@ pub mod definitions;
 pub mod diagnostic_items;
 pub use rustc_span::def_id;
 mod hir;
-pub mod hir_id;
+pub use rustc_hir_id::{self as hir_id, *};
 pub mod intravisit;
 pub mod lang_items;
 pub mod lints;
@@ -41,7 +38,6 @@ mod tests;
 
 #[doc(no_inline)]
 pub use hir::*;
-pub use hir_id::*;
 pub use lang_items::{LangItem, LanguageItems};
 pub use stability::*;
 pub use stable_hash_impls::HashStableContext;
diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs
index c55a41eb2b7..061ec786dc8 100644
--- a/compiler/rustc_hir/src/lints.rs
+++ b/compiler/rustc_hir/src/lints.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_macros::HashStable_Generic;
 use rustc_span::Span;
 
-use crate::HirId;
+use crate::{AttrPath, HirId, Target};
 
 #[derive(Debug)]
 pub struct DelayedLints {
@@ -34,4 +34,5 @@ pub enum AttributeLintKind {
     UnusedDuplicate { this: Span, other: Span, warning: bool },
     IllFormedAttributeInput { suggestions: Vec<String> },
     EmptyAttribute { first_span: Span },
+    InvalidTarget { name: AttrPath, target: Target, applied: Vec<String>, only: &'static str },
 }
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index ecc608d437b..16e8bac3d8a 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -5,7 +5,7 @@ use crate::HashIgnoredAttrId;
 use crate::hir::{
     AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId,
 };
-use crate::hir_id::{HirId, ItemLocalId};
+use crate::hir_id::ItemLocalId;
 use crate::lints::DelayedLints;
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
@@ -15,25 +15,6 @@ pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStabl
     fn hash_attr_id(&mut self, id: &HashIgnoredAttrId, hasher: &mut StableHasher);
 }
 
-impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
-    type KeyType = (DefPathHash, ItemLocalId);
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
-        let def_path_hash = self.owner.def_id.to_stable_hash_key(hcx);
-        (def_path_hash, self.local_id)
-    }
-}
-
-impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemLocalId {
-    type KeyType = ItemLocalId;
-
-    #[inline]
-    fn to_stable_hash_key(&self, _: &HirCtx) -> ItemLocalId {
-        *self
-    }
-}
-
 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for BodyId {
     type KeyType = (DefPathHash, ItemLocalId);
 
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index d617f44f8d8..dcac51b10b4 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -6,23 +6,34 @@
 
 use std::fmt::{self, Display};
 
+use rustc_ast::visit::AssocCtxt;
+use rustc_ast::{AssocItemKind, ForeignItemKind, ast};
+use rustc_macros::HashStable_Generic;
+
 use crate::def::DefKind;
 use crate::{Item, ItemKind, TraitItem, TraitItemKind, hir};
 
-#[derive(Copy, Clone, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug, Eq, HashStable_Generic)]
 pub enum GenericParamKind {
     Type,
     Lifetime,
     Const,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug, Eq, HashStable_Generic)]
 pub enum MethodKind {
-    Trait { body: bool },
+    /// Method in a `trait Trait` block
+    Trait {
+        /// Whether a default is provided for this method
+        body: bool,
+    },
+    /// Method in a `impl Trait for Type` block
+    TraitImpl,
+    /// Method in a `impl Type` block
     Inherent,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug, Eq, HashStable_Generic)]
 pub enum Target {
     ExternCrate,
     Use,
@@ -57,6 +68,9 @@ pub enum Target {
     PatField,
     ExprField,
     WherePredicate,
+    MacroCall,
+    Crate,
+    Delegation { mac: bool },
 }
 
 impl Display for Target {
@@ -65,6 +79,8 @@ impl Display for Target {
     }
 }
 
+rustc_error_messages::into_diag_arg_using_display!(Target);
+
 impl Target {
     pub fn is_associated_item(self) -> bool {
         match self {
@@ -98,7 +114,10 @@ impl Target {
             | Target::Param
             | Target::PatField
             | Target::ExprField
-            | Target::WherePredicate => false,
+            | Target::MacroCall
+            | Target::Crate
+            | Target::WherePredicate
+            | Target::Delegation { .. } => false,
         }
     }
 
@@ -146,6 +165,39 @@ impl Target {
         }
     }
 
+    pub fn from_ast_item(item: &ast::Item) -> Target {
+        match item.kind {
+            ast::ItemKind::ExternCrate(..) => Target::ExternCrate,
+            ast::ItemKind::Use(..) => Target::Use,
+            ast::ItemKind::Static { .. } => Target::Static,
+            ast::ItemKind::Const(..) => Target::Const,
+            ast::ItemKind::Fn { .. } => Target::Fn,
+            ast::ItemKind::Mod(..) => Target::Mod,
+            ast::ItemKind::ForeignMod { .. } => Target::ForeignMod,
+            ast::ItemKind::GlobalAsm { .. } => Target::GlobalAsm,
+            ast::ItemKind::TyAlias(..) => Target::TyAlias,
+            ast::ItemKind::Enum(..) => Target::Enum,
+            ast::ItemKind::Struct(..) => Target::Struct,
+            ast::ItemKind::Union(..) => Target::Union,
+            ast::ItemKind::Trait(..) => Target::Trait,
+            ast::ItemKind::TraitAlias(..) => Target::TraitAlias,
+            ast::ItemKind::Impl(ref i) => Target::Impl { of_trait: i.of_trait.is_some() },
+            ast::ItemKind::MacCall(..) => Target::MacroCall,
+            ast::ItemKind::MacroDef(..) => Target::MacroDef,
+            ast::ItemKind::Delegation(..) => Target::Delegation { mac: false },
+            ast::ItemKind::DelegationMac(..) => Target::Delegation { mac: true },
+        }
+    }
+
+    pub fn from_foreign_item_kind(kind: &ast::ForeignItemKind) -> Target {
+        match kind {
+            ForeignItemKind::Static(_) => Target::ForeignStatic,
+            ForeignItemKind::Fn(_) => Target::ForeignFn,
+            ForeignItemKind::TyAlias(_) => Target::ForeignTy,
+            ForeignItemKind::MacCall(_) => Target::MacroCall,
+        }
+    }
+
     pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
         match trait_item.kind {
             TraitItemKind::Const(..) => Target::AssocConst,
@@ -183,12 +235,40 @@ impl Target {
         }
     }
 
+    pub fn from_assoc_item_kind(kind: &ast::AssocItemKind, assoc_ctxt: AssocCtxt) -> Target {
+        match kind {
+            AssocItemKind::Const(_) => Target::AssocConst,
+            AssocItemKind::Fn(f) => Target::Method(match assoc_ctxt {
+                AssocCtxt::Trait => MethodKind::Trait { body: f.body.is_some() },
+                AssocCtxt::Impl { of_trait } => {
+                    if of_trait {
+                        MethodKind::TraitImpl
+                    } else {
+                        MethodKind::Inherent
+                    }
+                }
+            }),
+            AssocItemKind::Type(_) => Target::AssocTy,
+            AssocItemKind::Delegation(_) => Target::Delegation { mac: false },
+            AssocItemKind::DelegationMac(_) => Target::Delegation { mac: true },
+            AssocItemKind::MacCall(_) => Target::MacroCall,
+        }
+    }
+
+    pub fn from_expr(expr: &ast::Expr) -> Self {
+        match &expr.kind {
+            ast::ExprKind::Closure(..) | ast::ExprKind::Gen(..) => Self::Closure,
+            ast::ExprKind::Paren(e) => Self::from_expr(&e),
+            _ => Self::Expression,
+        }
+    }
+
     pub fn name(self) -> &'static str {
         match self {
             Target::ExternCrate => "extern crate",
             Target::Use => "use",
-            Target::Static => "static item",
-            Target::Const => "constant item",
+            Target::Static => "static",
+            Target::Const => "constant",
             Target::Fn => "function",
             Target::Closure => "closure",
             Target::Mod => "module",
@@ -202,8 +282,7 @@ impl Target {
             Target::Union => "union",
             Target::Trait => "trait",
             Target::TraitAlias => "trait alias",
-            Target::Impl { of_trait: false } => "inherent implementation block",
-            Target::Impl { of_trait: true } => "trait implementation block",
+            Target::Impl { .. } => "implementation block",
             Target::Expression => "expression",
             Target::Statement => "statement",
             Target::Arm => "match arm",
@@ -212,12 +291,13 @@ impl Target {
                 MethodKind::Inherent => "inherent method",
                 MethodKind::Trait { body: false } => "required trait method",
                 MethodKind::Trait { body: true } => "provided trait method",
+                MethodKind::TraitImpl => "trait method in an impl block",
             },
             Target::AssocTy => "associated type",
             Target::ForeignFn => "foreign function",
             Target::ForeignStatic => "foreign static item",
             Target::ForeignTy => "foreign type",
-            Target::GenericParam { kind, has_default: _ } => match kind {
+            Target::GenericParam { kind, .. } => match kind {
                 GenericParamKind::Type => "type parameter",
                 GenericParamKind::Lifetime => "lifetime parameter",
                 GenericParamKind::Const => "const parameter",
@@ -227,6 +307,60 @@ impl Target {
             Target::PatField => "pattern field",
             Target::ExprField => "struct field",
             Target::WherePredicate => "where predicate",
+            Target::MacroCall => "macro call",
+            Target::Crate => "crate",
+            Target::Delegation { .. } => "delegation",
+        }
+    }
+
+    pub fn plural_name(self) -> &'static str {
+        match self {
+            Target::ExternCrate => "extern crates",
+            Target::Use => "use statements",
+            Target::Static => "statics",
+            Target::Const => "constants",
+            Target::Fn => "functions",
+            Target::Closure => "closures",
+            Target::Mod => "modules",
+            Target::ForeignMod => "foreign modules",
+            Target::GlobalAsm => "global asms",
+            Target::TyAlias => "type aliases",
+            Target::Enum => "enums",
+            Target::Variant => "enum variants",
+            Target::Struct => "structs",
+            Target::Field => "struct fields",
+            Target::Union => "unions",
+            Target::Trait => "traits",
+            Target::TraitAlias => "trait aliases",
+            Target::Impl { of_trait: false } => "inherent impl blocks",
+            Target::Impl { of_trait: true } => "trait impl blocks",
+            Target::Expression => "expressions",
+            Target::Statement => "statements",
+            Target::Arm => "match arms",
+            Target::AssocConst => "associated consts",
+            Target::Method(kind) => match kind {
+                MethodKind::Inherent => "inherent methods",
+                MethodKind::Trait { body: false } => "required trait methods",
+                MethodKind::Trait { body: true } => "provided trait methods",
+                MethodKind::TraitImpl => "trait methods in impl blocks",
+            },
+            Target::AssocTy => "associated types",
+            Target::ForeignFn => "foreign functions",
+            Target::ForeignStatic => "foreign statics",
+            Target::ForeignTy => "foreign types",
+            Target::GenericParam { kind, has_default: _ } => match kind {
+                GenericParamKind::Type => "type parameters",
+                GenericParamKind::Lifetime => "lifetime parameters",
+                GenericParamKind::Const => "const parameters",
+            },
+            Target::MacroDef => "macro defs",
+            Target::Param => "function params",
+            Target::PatField => "pattern fields",
+            Target::ExprField => "struct fields",
+            Target::WherePredicate => "where predicates",
+            Target::MacroCall => "macro calls",
+            Target::Crate => "crates",
+            Target::Delegation { .. } => "delegations",
         }
     }
 }
diff --git a/compiler/rustc_hir/src/version.rs b/compiler/rustc_hir/src/version.rs
index ab5ab026b4c..bc2c38a4935 100644
--- a/compiler/rustc_hir/src/version.rs
+++ b/compiler/rustc_hir/src/version.rs
@@ -1,6 +1,8 @@
+use std::borrow::Cow;
 use std::fmt::{self, Display};
 use std::sync::OnceLock;
 
+use rustc_error_messages::{DiagArgValue, IntoDiagArg};
 use rustc_macros::{
     Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
 };
@@ -45,3 +47,9 @@ impl Display for RustcVersion {
         write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
     }
 }
+
+impl IntoDiagArg for RustcVersion {
+    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
+        DiagArgValue::Str(Cow::Owned(self.to_string()))
+    }
+}