1#![allow(internal_features)]
4#![feature(negative_impls)]
5#![feature(rustc_attrs)]
6
7use std::fmt::{self, Debug};
8
9use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
10use rustc_macros::{Decodable, Encodable, HashStable_Generic};
11pub use rustc_span::HashStableContext;
12use rustc_span::def_id::{CRATE_DEF_ID, DefId, DefIndex, DefPathHash, LocalDefId};
13
14#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
15pub struct OwnerId {
16 pub def_id: LocalDefId,
17}
18
19impl Debug for OwnerId {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 Debug::fmt(&self.def_id, f)
23 }
24}
25
26impl From<OwnerId> for HirId {
27 fn from(owner: OwnerId) -> HirId {
28 HirId { owner, local_id: ItemLocalId::ZERO }
29 }
30}
31
32impl From<OwnerId> for DefId {
33 fn from(value: OwnerId) -> Self {
34 value.to_def_id()
35 }
36}
37
38impl OwnerId {
39 #[inline]
40 pub fn to_def_id(self) -> DefId {
41 self.def_id.to_def_id()
42 }
43}
44
45impl rustc_index::Idx for OwnerId {
46 #[inline]
47 fn new(idx: usize) -> Self {
48 OwnerId { def_id: LocalDefId { local_def_index: DefIndex::from_usize(idx) } }
49 }
50
51 #[inline]
52 fn index(self) -> usize {
53 self.def_id.local_def_index.as_usize()
54 }
55}
56
57impl<CTX: HashStableContext> HashStable<CTX> for OwnerId {
58 #[inline]
59 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
60 self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
61 }
62}
63
64impl<CTX: HashStableContext> ToStableHashKey<CTX> for OwnerId {
65 type KeyType = DefPathHash;
66
67 #[inline]
68 fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
69 hcx.def_path_hash(self.to_def_id())
70 }
71}
72
73#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
84#[rustc_pass_by_value]
85pub struct HirId {
86 pub owner: OwnerId,
87 pub local_id: ItemLocalId,
88}
89
90impl !Ord for HirId {}
94impl !PartialOrd for HirId {}
95
96impl Debug for HirId {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(f, "HirId({:?}.{:?})", self.owner, self.local_id)
101 }
102}
103
104impl HirId {
105 pub const INVALID: HirId =
107 HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::INVALID };
108
109 #[inline]
110 pub fn expect_owner(self) -> OwnerId {
111 assert_eq!(self.local_id.index(), 0);
112 self.owner
113 }
114
115 #[inline]
116 pub fn as_owner(self) -> Option<OwnerId> {
117 if self.local_id.index() == 0 { Some(self.owner) } else { None }
118 }
119
120 #[inline]
121 pub fn is_owner(self) -> bool {
122 self.local_id.index() == 0
123 }
124
125 #[inline]
126 pub fn make_owner(owner: LocalDefId) -> Self {
127 Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO }
128 }
129}
130
131impl fmt::Display for HirId {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 write!(f, "{self:?}")
134 }
135}
136
137rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
138rustc_data_structures::define_id_collections!(
139 ItemLocalMap,
140 ItemLocalSet,
141 ItemLocalMapEntry,
142 ItemLocalId
143);
144
145rustc_index::newtype_index! {
146 #[derive(HashStable_Generic)]
155 #[encodable]
156 #[orderable]
157 pub struct ItemLocalId {}
158}
159
160impl ItemLocalId {
161 pub const INVALID: ItemLocalId = ItemLocalId::MAX;
163}
164
165impl StableOrd for ItemLocalId {
166 const CAN_USE_UNSTABLE_SORT: bool = true;
167
168 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
171}
172
173pub const CRATE_HIR_ID: HirId =
175 HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::ZERO };
176
177pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID };
178
179impl<CTX: rustc_span::HashStableContext> ToStableHashKey<CTX> for HirId {
180 type KeyType = (DefPathHash, ItemLocalId);
181
182 #[inline]
183 fn to_stable_hash_key(&self, hcx: &CTX) -> (DefPathHash, ItemLocalId) {
184 let def_path_hash = self.owner.def_id.to_stable_hash_key(hcx);
185 (def_path_hash, self.local_id)
186 }
187}
188
189impl<CTX: HashStableContext> ToStableHashKey<CTX> for ItemLocalId {
190 type KeyType = ItemLocalId;
191
192 #[inline]
193 fn to_stable_hash_key(&self, _: &CTX) -> ItemLocalId {
194 *self
195 }
196}