Skip to main content

Module rtti

Module rtti 

Source
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§

AstNodeClass
Implemented by every concrete AST node type — the analog of the LUAU_RTTI(Class) macro, which expands to static int ClassIndex().
AstNodeRef
node->is<T>() — does this node have T’s dynamic type?
CstNodeClass
CST analog of AstNodeClass — the LUAU_CST_RTTI(Class) macro, which expands to static int CstClassIndex(). CST nodes form a separate RTTI space (gCstRttiIndex) and a CstNode* is never cross-cast to an AstNode*, so reusing ast_rtti_index for 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
const variant of ast_node_as for *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 positive i32 so it can never collide with a future “no class” sentinel (e.g. -1).
cst_node_as
cstNode->as<T>() — downcast a base *mut CstNode to *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 so LUAU_CST_RTTI(Class) translations can read naturally as cst_rtti_index("CstX").