Skip to main content

rustc_ast/
node_id.rs

1use std::fmt;
2
3use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher};
4use rustc_span::LocalExpnId;
5
6#[automatically_derived]
impl ::core::marker::Copy for NodeId { }
#[doc = " The [`NodeId`] used to represent the root of the crate."]
pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0);
impl NodeId {
    #[doc = r" Maximum value the index can take, as a `u32`."]
    pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
    #[doc = r" Maximum value the index can take."]
    pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
    #[doc = r" Zero value of the index."]
    pub const ZERO: Self = Self::from_u32(0);
    #[doc = r" Creates a new index from a given `usize`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_usize(value: usize) -> Self {
        if !(value <= (0xFFFF_FF00 as usize)) {
            ::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
        };
        unsafe { Self::from_u32_unchecked(value as u32) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u32(value: u32) -> Self {
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u16`."]
    #[doc = r""]
    #[doc = r" # Panics"]
    #[doc = r""]
    #[doc = r" Will panic if `value` exceeds `MAX`."]
    #[inline]
    pub const fn from_u16(value: u16) -> Self {
        let value = value as u32;
        if !(value <= 0xFFFF_FF00) {
            ::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
        };
        unsafe { Self::from_u32_unchecked(value) }
    }
    #[doc = r" Creates a new index from a given `u32`."]
    #[doc = r""]
    #[doc = r" # Safety"]
    #[doc = r""]
    #[doc =
    r" The provided value must be less than or equal to the maximum value for the newtype."]
    #[doc =
    r" Providing a value outside this range is undefined due to layout restrictions."]
    #[doc = r""]
    #[doc = r" Prefer using `from_u32`."]
    #[inline]
    pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
        Self {
            private_use_as_methods_instead: unsafe {
                std::mem::transmute(value)
            },
        }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn index(self) -> usize { self.as_usize() }
    #[doc = r" Extracts the value of this index as a `u32`."]
    #[inline]
    pub const fn as_u32(self) -> u32 {
        unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
    }
    #[doc = r" Extracts the value of this index as a `usize`."]
    #[inline]
    pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for NodeId {
    type Output = Self;
    #[inline]
    fn add(self, other: usize) -> Self {
        Self::from_usize(self.index() + other)
    }
}
impl std::ops::AddAssign<usize> for NodeId {
    #[inline]
    fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for NodeId {
    #[inline]
    fn new(value: usize) -> Self { Self::from_usize(value) }
    #[inline]
    fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for NodeId {
    #[inline]
    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
        <usize as
                ::std::iter::Step>::steps_between(&Self::index(*start),
            &Self::index(*end))
    }
    #[inline]
    fn forward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_add(u).map(Self::from_usize)
    }
    #[inline]
    fn backward_checked(start: Self, u: usize) -> Option<Self> {
        Self::index(start).checked_sub(u).map(Self::from_usize)
    }
    #[inline]
    fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_add(u);
        (Self::from_usize(s), o)
    }
    #[inline]
    fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
        let (s, o) = Self::index(start).overflowing_sub(u);
        (Self::from_usize(s), o)
    }
}
impl ::std::cmp::Ord for NodeId {
    #[inline]
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.as_u32().cmp(&other.as_u32())
    }
}
impl ::std::cmp::PartialOrd for NodeId {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}
impl From<NodeId> for u32 {
    #[inline]
    fn from(v: NodeId) -> u32 { v.as_u32() }
}
impl From<NodeId> for usize {
    #[inline]
    fn from(v: NodeId) -> usize { v.as_usize() }
}
impl From<usize> for NodeId {
    #[inline]
    fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for NodeId {
    #[inline]
    fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for NodeId {}
impl ::std::cmp::PartialEq for NodeId {
    fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for NodeId {}
impl ::std::hash::Hash for NodeId {
    fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
        self.as_u32().hash(state)
    }
}
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for NodeId
    {
    fn decode(d: &mut D) -> Self { Self::from_u32(d.read_u32()) }
}
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for NodeId
    {
    fn encode(&self, e: &mut E) { e.emit_u32(self.as_u32()); }
}
impl ::std::fmt::Debug for NodeId {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("NodeId({0})", self.as_u32()))
    }
}rustc_index::newtype_index! {
7    /// Identifies an AST node.
8    ///
9    /// This identifies top-level definitions, expressions, and everything in between.
10    /// This is later turned into [`DefId`] and `HirId` for the HIR.
11    ///
12    /// [`DefId`]: rustc_span::def_id::DefId
13    #[encodable]
14    #[orderable]
15    #[debug_format = "NodeId({})"]
16    pub struct NodeId {
17        /// The [`NodeId`] used to represent the root of the crate.
18        const CRATE_NODE_ID = 0;
19    }
20}
21
22impl StableHash for NodeId {
23    #[inline]
24    fn stable_hash<Hcx: StableHashCtxt>(&self, _: &mut Hcx, _: &mut StableHasher) {
25        // This impl is never called but is necessary for types implementing `StableHash` such as
26        // `MainDefinition` and `DocLinkResMap` (both of which occur in `ResolverGlobalCtxt`).
27        {
    ::core::panicking::panic_fmt(format_args!("Node IDs should not appear in incremental state"));
};panic!("Node IDs should not appear in incremental state");
28    }
29}
30
31pub type NodeMap<T> = ::rustc_data_structures::unord::UnordMap<NodeId, T>;
pub type NodeSet = ::rustc_data_structures::unord::UnordSet<NodeId>;
pub type NodeMapEntry<'a, T> =
    ::rustc_data_structures::fx::StdEntry<'a, NodeId, T>;rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId);
32
33/// When parsing and at the beginning of doing expansions, we initially give all AST nodes
34/// this dummy AST [`NodeId`]. Then, during a later phase of expansion, we renumber them
35/// to have small, positive IDs.
36pub const DUMMY_NODE_ID: NodeId = NodeId::MAX;
37
38impl NodeId {
39    pub fn placeholder_from_expn_id(expn_id: LocalExpnId) -> Self {
40        NodeId::from_u32(expn_id.as_u32())
41    }
42
43    pub fn placeholder_to_expn_id(self) -> LocalExpnId {
44        LocalExpnId::from_u32(self.as_u32())
45    }
46}
47
48impl fmt::Display for NodeId {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        fmt::Display::fmt(&self.as_u32(), f)
51    }
52}