1use crate::types::{Type, TypeBound};
3use crate::Node;
4
5use derive_more::From as DerFrom;
6use smol_str::SmolStr;
7
8use super::{AliasDecl, OpTag};
9
10pub trait NodeHandle: Clone {
13 const TAG: OpTag;
15
16 fn node(&self) -> Node;
18
19 #[inline]
21 fn tag(&self) -> OpTag {
22 Self::TAG
23 }
24
25 fn try_cast<T: NodeHandle + From<Node>>(&self) -> Option<T> {
27 T::TAG.is_superset(Self::TAG).then(|| self.node().into())
28 }
29
30 fn can_hold(tag: OpTag) -> bool {
32 Self::TAG.is_superset(tag)
33 }
34}
35
36pub trait ContainerHandle: NodeHandle {
40 type ChildrenHandle: NodeHandle;
42}
43
44#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
45pub struct DataflowOpID(Node);
47
48#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
49pub struct DfgID(Node);
51
52#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
53pub struct CfgID(Node);
55
56#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
57pub struct ModuleRootID(Node);
59
60#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
61pub struct ModuleID(Node);
63
64#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
65pub struct FuncID<const DEF: bool>(Node);
71
72#[derive(Debug, Clone, PartialEq, Eq)]
73pub struct AliasID<const DEF: bool> {
79 node: Node,
80 name: SmolStr,
81 bound: TypeBound,
82}
83
84impl<const DEF: bool> AliasID<DEF> {
85 pub fn new(node: Node, name: SmolStr, bound: TypeBound) -> Self {
87 Self { node, name, bound }
88 }
89
90 pub fn get_alias_type(&self) -> Type {
92 Type::new_alias(AliasDecl::new(self.name.clone(), self.bound))
93 }
94 pub fn get_name(&self) -> &SmolStr {
96 &self.name
97 }
98}
99
100#[derive(DerFrom, Debug, Clone, PartialEq, Eq)]
101pub struct ConstID(Node);
103
104#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
105pub struct BasicBlockID(Node);
107
108#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
109pub struct CaseID(Node);
111
112#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
113pub struct TailLoopID(Node);
115
116#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
117pub struct ConditionalID(Node);
119
120#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
121pub struct DataflowParentID(Node);
123
124macro_rules! impl_nodehandle {
130 ($name:ident, $tag:expr) => {
131 impl_nodehandle!($name, $tag, 0);
132 };
133 ($name:ident, $tag:expr, $node_attr:tt) => {
134 impl NodeHandle for $name {
135 const TAG: OpTag = $tag;
136
137 #[inline]
138 fn node(&self) -> Node {
139 self.$node_attr
140 }
141 }
142 };
143}
144
145impl_nodehandle!(DataflowParentID, OpTag::DataflowParent);
146impl_nodehandle!(DataflowOpID, OpTag::DataflowChild);
147impl_nodehandle!(ConditionalID, OpTag::Conditional);
148impl_nodehandle!(CaseID, OpTag::Case);
149impl_nodehandle!(DfgID, OpTag::Dfg);
150impl_nodehandle!(TailLoopID, OpTag::TailLoop);
151impl_nodehandle!(CfgID, OpTag::Cfg);
152
153impl_nodehandle!(ModuleRootID, OpTag::ModuleRoot);
154impl_nodehandle!(ModuleID, OpTag::ModuleOp);
155impl_nodehandle!(ConstID, OpTag::Const);
156
157impl_nodehandle!(BasicBlockID, OpTag::DataflowBlock);
158
159impl<const DEF: bool> NodeHandle for FuncID<DEF> {
160 const TAG: OpTag = OpTag::Function;
161 #[inline]
162 fn node(&self) -> Node {
163 self.0
164 }
165}
166
167impl<const DEF: bool> NodeHandle for AliasID<DEF> {
168 const TAG: OpTag = OpTag::Alias;
169 #[inline]
170 fn node(&self) -> Node {
171 self.node
172 }
173}
174
175impl NodeHandle for Node {
176 const TAG: OpTag = OpTag::Any;
177 #[inline]
178 fn node(&self) -> Node {
179 *self
180 }
181}
182
183macro_rules! impl_containerHandle {
185 ($name:path, $children:ident) => {
186 impl ContainerHandle for $name {
187 type ChildrenHandle = $children;
188 }
189 };
190}
191
192impl_containerHandle!(DataflowParentID, DataflowOpID);
193impl_containerHandle!(DfgID, DataflowOpID);
194impl_containerHandle!(TailLoopID, DataflowOpID);
195impl_containerHandle!(ConditionalID, CaseID);
196impl_containerHandle!(CaseID, DataflowOpID);
197impl_containerHandle!(ModuleRootID, ModuleID);
198impl_containerHandle!(CfgID, BasicBlockID);
199impl_containerHandle!(BasicBlockID, DataflowOpID);
200impl_containerHandle!(FuncID<true>, DataflowOpID);
201impl_containerHandle!(AliasID<true>, DataflowOpID);