macro_rules! new_id {
($(#[$attr:meta])* $vis:vis $name:ident: $data_ty:ty) => {
$(#[$attr])*
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
$vis struct $name {
/// The layout of the data is up to the driver implementation. The API will never
data: $data_ty,
}
#[cfg(feature = "driver-api")]
impl $name {
#[must_use]
pub fn new(data: $data_ty) -> Self {
Self { data }
}
pub fn data(self) -> $data_ty {
self.data
}
}
impl std::fmt::Debug for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(concat!(stringify!($name), "(..)")).finish()
}
}
};
}
use new_id;
use crate::private::Sealed;
new_id!(
pub CrateId: u32
);
new_id! {
pub ItemId: u64
}
new_id! {
pub VariantId: u64
}
new_id! {
pub FieldId: u64
}
new_id! {
pub TyDefId: u64
}
new_id! {
pub GenericId: u64
}
new_id! {
pub MacroId: u64
}
new_id! {
pub BodyId: u64
}
new_id! {
pub VarId: u64
}
new_id! {
pub ExprId: u64
}
new_id! {
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
pub(crate) SpanId: u64
}
new_id! {
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
pub(crate) SpanSrcId: u32
}
new_id! {
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
pub(crate) ExpnId: u64
}
new_id! {
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
pub(crate) SymbolId: u32
}
new_id! {
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
pub(crate) DriverTyId: u64
}
new_id! {
pub StmtId: u64
}
#[repr(C)]
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub enum NodeId {
Expr(ExprId),
Item(ItemId),
Stmt(StmtId),
Body(BodyId),
Field(FieldId),
Variant(VariantId),
}
macro_rules! impl_into_node_id_for {
($variant:ident, $ty:ty) => {
impl From<$ty> for NodeId {
fn from(value: $ty) -> Self {
NodeId::$variant(value)
}
}
impl From<&$ty> for NodeId {
fn from(value: &$ty) -> Self {
NodeId::$variant(*value)
}
}
};
}
impl_into_node_id_for!(Expr, ExprId);
impl_into_node_id_for!(Item, ItemId);
impl_into_node_id_for!(Stmt, StmtId);
impl_into_node_id_for!(Body, BodyId);
impl_into_node_id_for!(Field, FieldId);
impl_into_node_id_for!(Variant, VariantId);
pub trait HasNodeId: Sealed {
fn node_id(&self) -> NodeId;
}
impl<N: HasNodeId> HasNodeId for &N {
fn node_id(&self) -> NodeId {
(*self).node_id()
}
}
macro_rules! impl_identifiable_for {
($ty:ty$(, use $data_trait:path)?) => {
impl<'ast> $crate::common::HasNodeId for $ty {
fn node_id(&self) -> $crate::common::NodeId {
$(
use $data_trait;
)*
self.id().into()
}
}
};
}
pub(crate) use impl_identifiable_for;