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);