Walker: memoize DynamicSubgrammar resolution to bound the Box::leak

Node::DynamicSubgrammar factories build a Node from the WalkContext and
must Box::leak it (the Node enum's combinator children are &'static).
Leaking per walk grew unbounded under per-keystroke completion
(handoff-12 §2.1).

resolve_dynamic now memoizes on the schema state a factory reads
(table columns, current column, user-listed columns) keyed by factory
fn-pointer. Each distinct value-list shape leaks exactly once — total
leak bounded by distinct (schema × form) combinations, not keystroke
count. TableColumn gains Hash for the cache key.

The handoff's original arena sketch needed a lifetime-generic Node
(major refactor); memoization gets the same bound without it.
This commit is contained in:
claude@clouddev1
2026-05-15 22:06:33 +00:00
parent 911a537a83
commit 9bbb96e735
2 changed files with 122 additions and 7 deletions
+1 -1
View File
@@ -49,7 +49,7 @@ pub struct SchemaCache {
/// One column's user-facing type info, scoped to a table
/// (ADR-0024 §Phase D, §WalkContext).
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TableColumn {
pub name: String,
pub user_type: crate::dsl::types::Type,