1 use crate::def_id
::{DefId, DefIndex, LocalDefId, CRATE_DEF_ID}
;
2 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher, StableOrd, ToStableHashKey}
;
3 use rustc_span
::{def_id::DefPathHash, HashStableContext}
;
6 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
7 #[derive(Encodable, Decodable)]
9 pub def_id
: LocalDefId
,
12 impl From
<OwnerId
> for HirId
{
13 fn from(owner
: OwnerId
) -> HirId
{
14 HirId { owner, local_id: ItemLocalId::from_u32(0) }
20 pub fn to_def_id(self) -> DefId
{
21 self.def_id
.to_def_id()
25 impl rustc_index
::vec
::Idx
for OwnerId
{
27 fn new(idx
: usize) -> Self {
28 OwnerId { def_id: LocalDefId { local_def_index: DefIndex::from_usize(idx) }
}
32 fn index(self) -> usize {
33 self.def_id
.local_def_index
.as_usize()
37 impl<CTX
: HashStableContext
> HashStable
<CTX
> for OwnerId
{
39 fn hash_stable(&self, hcx
: &mut CTX
, hasher
: &mut StableHasher
) {
40 self.to_stable_hash_key(hcx
).hash_stable(hcx
, hasher
);
44 impl<CTX
: HashStableContext
> ToStableHashKey
<CTX
> for OwnerId
{
45 type KeyType
= DefPathHash
;
48 fn to_stable_hash_key(&self, hcx
: &CTX
) -> DefPathHash
{
49 hcx
.def_path_hash(self.to_def_id())
53 /// Uniquely identifies a node in the HIR of the current crate. It is
54 /// composed of the `owner`, which is the `LocalDefId` of the directly enclosing
55 /// `hir::Item`, `hir::TraitItem`, or `hir::ImplItem` (i.e., the closest "item-like"),
56 /// and the `local_id` which is unique within the given owner.
58 /// This two-level structure makes for more stable values: One can move an item
59 /// around within the source code, or add or remove stuff before it, without
60 /// the `local_id` part of the `HirId` changing, which is a very useful property in
61 /// incremental compilation where we have to persist things through changes to
63 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
64 #[derive(Encodable, Decodable, HashStable_Generic)]
65 #[rustc_pass_by_value]
68 pub local_id
: ItemLocalId
,
72 /// Signal local id which should never be used.
73 pub const INVALID
: HirId
=
74 HirId { owner: OwnerId { def_id: CRATE_DEF_ID }
, local_id
: ItemLocalId
::INVALID
};
77 pub fn expect_owner(self) -> OwnerId
{
78 assert_eq
!(self.local_id
.index(), 0);
83 pub fn as_owner(self) -> Option
<OwnerId
> {
84 if self.local_id
.index() == 0 { Some(self.owner) }
else { None }
88 pub fn is_owner(self) -> bool
{
89 self.local_id
.index() == 0
93 pub fn make_owner(owner
: LocalDefId
) -> Self {
94 Self { owner: OwnerId { def_id: owner }
, local_id
: ItemLocalId
::from_u32(0) }
97 pub fn index(self) -> (usize, usize) {
99 rustc_index
::vec
::Idx
::index(self.owner
.def_id
),
100 rustc_index
::vec
::Idx
::index(self.local_id
),
105 impl fmt
::Display
for HirId
{
106 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
107 write
!(f
, "{:?}", self)
112 fn cmp(&self, other
: &Self) -> std
::cmp
::Ordering
{
113 (self.index()).cmp(&(other
.index()))
117 impl PartialOrd
for HirId
{
118 fn partial_cmp(&self, other
: &Self) -> Option
<std
::cmp
::Ordering
> {
119 Some(self.cmp(other
))
123 rustc_data_structures
::define_stable_id_collections
!(HirIdMap
, HirIdSet
, HirIdMapEntry
, HirId
);
124 rustc_data_structures
::define_id_collections
!(
131 rustc_index
::newtype_index
! {
132 /// An `ItemLocalId` uniquely identifies something within a given "item-like";
133 /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no
134 /// guarantee that the numerical value of a given `ItemLocalId` corresponds to
135 /// the node's position within the owning item in any way, but there is a
136 /// guarantee that the `LocalItemId`s within an owner occupy a dense range of
137 /// integers starting at zero, so a mapping that maps all or most nodes within
138 /// an "item-like" to something else can be implemented by a `Vec` instead of a
139 /// tree or hash map.
140 #[derive(HashStable_Generic)]
141 pub struct ItemLocalId { .. }
145 /// Signal local id which should never be used.
146 pub const INVALID
: ItemLocalId
= ItemLocalId
::MAX
;
149 // Safety: Ord is implement as just comparing the LocalItemId's numerical
150 // values and these are not changed by (de-)serialization.
151 unsafe impl StableOrd
for ItemLocalId {}
153 /// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
154 pub const CRATE_HIR_ID
: HirId
=
155 HirId { owner: OwnerId { def_id: CRATE_DEF_ID }
, local_id
: ItemLocalId
::from_u32(0) };
157 pub const CRATE_OWNER_ID
: OwnerId
= OwnerId { def_id: CRATE_DEF_ID }
;