1 use crate::def_id::{LocalDefId, CRATE_DEF_INDEX}; 2 use std::fmt; 3 4 /// Uniquely identifies a node in the HIR of the current crate. It is 5 /// composed of the `owner`, which is the `LocalDefId` of the directly enclosing 6 /// `hir::Item`, `hir::TraitItem`, or `hir::ImplItem` (i.e., the closest "item-like"), 7 /// and the `local_id` which is unique within the given owner. 8 /// 9 /// This two-level structure makes for more stable values: One can move an item 10 /// around within the source code, or add or remove stuff before it, without 11 /// the `local_id` part of the `HirId` changing, which is a very useful property in 12 /// incremental compilation where we have to persist things through changes to 13 /// the code base. 14 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] 15 #[derive(Encodable, Decodable)] 16 pub struct HirId { 17 pub owner: LocalDefId, 18 pub local_id: ItemLocalId, 19 } 20 21 impl HirId { expect_owner(self) -> LocalDefId22 pub fn expect_owner(self) -> LocalDefId { 23 assert_eq!(self.local_id.index(), 0); 24 self.owner 25 } 26 as_owner(self) -> Option<LocalDefId>27 pub fn as_owner(self) -> Option<LocalDefId> { 28 if self.local_id.index() == 0 { Some(self.owner) } else { None } 29 } 30 31 #[inline] make_owner(owner: LocalDefId) -> Self32 pub fn make_owner(owner: LocalDefId) -> Self { 33 Self { owner, local_id: ItemLocalId::from_u32(0) } 34 } 35 } 36 37 impl fmt::Display for HirId { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 39 write!(f, "{:?}", self) 40 } 41 } 42 43 rustc_data_structures::define_id_collections!(HirIdMap, HirIdSet, HirId); 44 rustc_data_structures::define_id_collections!(ItemLocalMap, ItemLocalSet, ItemLocalId); 45 46 rustc_index::newtype_index! { 47 /// An `ItemLocalId` uniquely identifies something within a given "item-like"; 48 /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no 49 /// guarantee that the numerical value of a given `ItemLocalId` corresponds to 50 /// the node's position within the owning item in any way, but there is a 51 /// guarantee that the `LocalItemId`s within an owner occupy a dense range of 52 /// integers starting at zero, so a mapping that maps all or most nodes within 53 /// an "item-like" to something else can be implemented by a `Vec` instead of a 54 /// tree or hash map. 55 pub struct ItemLocalId { .. } 56 } 57 rustc_data_structures::impl_stable_hash_via_hash!(ItemLocalId); 58 impl ItemLocalId { 59 /// Signal local id which should never be used. 60 pub const INVALID: ItemLocalId = ItemLocalId::MAX; 61 } 62 63 /// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_INDEX`. 64 pub const CRATE_HIR_ID: HirId = HirId { 65 owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, 66 local_id: ItemLocalId::from_u32(0), 67 }; 68