hax_rust_engine/ast/fragment.rs
1//! Enumeration types of any possible fragment of AST (`Fragment` / `FragmentRef`).
2//!
3//! Many components (diagnostics, logging, printers) want to refer to “some AST
4//! node” without knowing its concrete type. This module provides:
5//! - [`Fragment`]: an **owned** enum covering core AST node types.
6//! - [`FragmentRef`]: a **borrowed** counterpart.
7//!
8//! These are handy when implementing generic facilities such as error reporters,
9//! debugging helpers, or pretty-printers that need to branch on “what kind of
10//! node is this?” at runtime.
11//!
12//! ## Notes
13//! - Both enums are mechanically generated to stay in sync with the canonical
14//! AST types. If you add a new core AST node, update the macro invocation at
15//! the bottom of this file so `Fragment`/`FragmentRef` learn about it.
16//! - The [`Unknown`] variant exists as a last-resort placeholder when a value
17//! cannot be represented by a known variant. Prefer concrete variants when
18//! possible.
19
20use crate::ast::*;
21
22/// The `mk!` macro takes a flat list of AST type identifiers and expands to
23/// two enums:
24/// - `Fragment` with owned variants (`Foo(Foo)`), and
25/// - `FragmentRef<'a>` with borrowed variants (`Foo(&'a Foo)`).
26///
27/// The generated enums also implement the obvious `From<T>` conversions, making
28/// it ergonomic to wrap concrete AST values as fragments.
29macro_rules! mk {
30 ($($ty:ident),*) => {
31 #[derive_group_for_ast]
32 #[allow(missing_docs)]
33 /// An owned fragment of AST in hax.
34 pub enum Fragment {
35 $(
36 #[doc = concat!("An owned [`", stringify!($ty), "`] node.")]
37 $ty($ty),
38 )*
39 /// Represent an unknown node in the AST with a message.
40 Unknown(String),
41 }
42 #[derive(Copy)]
43 #[derive_group_for_ast_base]
44 #[derive(::serde::Serialize)]
45 #[allow(missing_docs)]
46 /// A borrowed fragment of AST in hax.
47 pub enum FragmentRef<'lt> {
48 $(
49 #[doc = concat!("A borrowed [`", stringify!($ty), "`] node.")]
50 $ty(&'lt $ty),
51 )*
52 }
53
54 $(
55 impl From<$ty> for Fragment {
56 fn from(fragment: $ty) -> Self {
57 Self::$ty(fragment)
58 }
59 }
60 impl<'lt> From<&'lt $ty> for FragmentRef<'lt> {
61 fn from(fragment: &'lt $ty) -> Self {
62 Self::$ty(fragment)
63 }
64 }
65 )*
66 };
67}
68
69#[hax_rust_engine_macros::replace(AstNodes => include(VisitableAstNodes))]
70mk!(GlobalId, AstNodes);