Expand description
AST RTTI mechanism — the faithful Rust analog of Luau’s
AstRtti<T>::value / LUAU_RTTI(Class) / AstNode::is<T>() / as<T>().
Reference: luau/Ast/include/Luau/Ast.h (the AstNode base + the
LUAU_RTTI macro).
In C++ every node carries a const int classIndex set at construction to a
per-type id, and node->as<T>() is classIndex == T::ClassIndex() ? static_cast<T*>(this) : nullptr. The cast is sound because Luau nodes are
standard-layout single-inheritance, so the base subobject sits at offset 0.
We reproduce that exactly: every node is #[repr(C)] with its parent as the
first field (pub base: Parent), so a *mut AstNode that actually points at
an AstExprGroup can be reinterpreted as *mut AstExprGroup once the class
index matches. The class index is a compile-time hash of the type name, so
each node file is self-contained (no shared mutable counter / central
registry to serialize against, unlike C++’s ++gAstRttiIndex). The exact
integer is irrelevant — only that it is unique per type and stable — which
the rtti_indices_unique test enforces over the full node set.
Traits§
- AstNode
Class - Implemented by every concrete AST node type — the analog of the
LUAU_RTTI(Class)macro, which expands tostatic int ClassIndex(). - AstNode
Ref node->is<T>()— does this node haveT’s dynamic type?- CstNode
Class - CST analog of
AstNodeClass— theLUAU_CST_RTTI(Class)macro, which expands tostatic int CstClassIndex(). CST nodes form a separate RTTI space (gCstRttiIndex) and aCstNode*is never cross-cast to anAstNode*, so reusingast_rtti_indexfor the index value is sound — uniqueness only has to hold among CST names ([tests::cst_rtti_indices_unique]).
Functions§
- ast_
node_ ⚠as node->as<T>()— downcast a base-node pointer to*mut T, or null when the dynamic type does not match.- ast_
node_ ⚠as_ const constvariant ofast_node_asfor*const AstNode.- ast_
node_ is - ast_
rtti_ index - Stable per-type class index, the analog of
AstRtti<Class>::value. FNV-1a over the class name, folded to a positivei32so it can never collide with a future “no class” sentinel (e.g.-1). - cst_
node_ ⚠as cstNode->as<T>()— downcast a base*mut CstNodeto*mut T, or null on mismatch.- cst_
node_ is cstNode->is<T>().- cst_
rtti_ index - CST spelling of
ast_rtti_index(CST and AST share the index function but separate index spaces). Provided soLUAU_CST_RTTI(Class)translations can read naturally ascst_rtti_index("CstX").