Problem
Supertype patterns — (statement) matching any concrete statement kind, and the narrowing forms (native (statement#lexical_declaration), deprecated tree-sitter (statement/lexical_declaration)) — are documented in docs/lang-reference.md and accepted by the parser and type checker, but cannot work at runtime: tree-sitter never produces nodes with the supertype's kind id. #417 makes them a loud compile error as an interim measure. This issue is the actual implementation.
Approach
Expand supertypes at link time, where the grammar is known:
plotnik-core's Grammar::subtypes() already returns the concrete kinds for a supertype (currently has zero consumers).
- In
crates/plotnik-compiler/src/analyze/link.rs, resolve a supertype node pattern to the set of concrete kind ids and lower it as an alternation over those kinds. Mechanically: a node-type set on the Match instruction, or an epsilon branch over per-kind matches — whichever the instruction encoding supports better. An inline kind-set avoids branch blowup for large supertypes like statement.
- Narrowing reads the subtype from the CST (the parser already records it on the node; native
#, deprecated /) and restricts the set to that subtype, validating that it is a subtype — error otherwise.
- A refinement on a concrete (non-supertype) head —
(binary_expression#foo) — is also an error. Today the subtype is silently ignored. Refinement is only meaningful on a supertype.
- Subtypes can themselves be supertypes (e.g.
declaration inside statement). Expand transitively.
- Type system: the narrowed form should surface the concrete node type in inferred types where possible.
Acceptance
Problem
Supertype patterns —
(statement)matching any concrete statement kind, and the narrowing forms (native(statement#lexical_declaration), deprecated tree-sitter(statement/lexical_declaration)) — are documented indocs/lang-reference.mdand accepted by the parser and type checker, but cannot work at runtime: tree-sitter never produces nodes with the supertype's kind id. #417 makes them a loud compile error as an interim measure. This issue is the actual implementation.Approach
Expand supertypes at link time, where the grammar is known:
plotnik-core'sGrammar::subtypes()already returns the concrete kinds for a supertype (currently has zero consumers).crates/plotnik-compiler/src/analyze/link.rs, resolve a supertype node pattern to the set of concrete kind ids and lower it as an alternation over those kinds. Mechanically: a node-type set on the Match instruction, or an epsilon branch over per-kind matches — whichever the instruction encoding supports better. An inline kind-set avoids branch blowup for large supertypes likestatement.#, deprecated/) and restricts the set to that subtype, validating that it is a subtype — error otherwise.(binary_expression#foo)— is also an error. Today the subtype is silently ignored. Refinement is only meaningful on a supertype.declarationinsidestatement). Expand transitively.Acceptance
(statement)* @sonlet x; foo;returns both statements.(statement#lexical_declaration)(and the deprecated(statement/lexical_declaration)) matches only lexical declarations.(statement#identifier)is a compile error (not a subtype).(binary_expression#anything)is a compile error (not a supertype).docs/lang-reference.md(which now use#) become conformance corpus cases (Conformance test layer for the compiler→VM seam #418).