Design: arbitrary comptime-evaluated expressions in Comptime(_) generic params #76

Open
opened 2026-09-30 02:19:38 +00:00 by jacksonopp · 1 comment
Owner

Follow-up to #67, split out rather than folded in.

#67 settled the checker semantics for Comptime(Int)-kinded generic params (Array(Int, N) sizes), but only for literal values — Array(Int, 3) works, Array(Int, computeSize()) doesn't. That ceiling is already baked into the AST/checker types from #66/#71:

  • GenericArg::Value holds a Spanned<Literal>, not a Spanned<Expr>.
  • InstantiationArg::Value holds a Literal, not a resolved comptime result.
  • check_array_size explicitly skips non-literal sizes, since Scope only tracks Ty, not values.

To support arbitrary comptime-evaluated expressions in Comptime(_) position, we need an actual comptime evaluator — not just a checker tweak. Open design questions for whoever picks this up:

  • What counts as comptime-evaluable? Literals and arithmetic on them, obviously. Named consts (let N = 3; Array(Int, N))? Calls to other functions, if those functions are themselves comptime-pure (Zig-style comptime-ness tracked through the call graph)?
  • AST change: GenericArg::Value would need to hold a Spanned<Expr> instead of a Literal, with the checker reducing it to a Literal/concrete value or failing with a diagnostic.
  • Where does evaluation live? Something like check_comptime_expr alongside check_expr, needing Scope (or a sibling) to track actual bound values, not just types.
  • Memoization: presumably a salsa-tracked query, so computeSize() isn't re-evaluated on every reference.
  • Failure mode: a new diagnostic for comptime-eval failure (calls something non-const, etc.), distinct from InvalidArraySize.

No implementation yet — this is a design/risk issue, same shape as #69.

Follow-up to #67, split out rather than folded in. #67 settled the checker semantics for `Comptime(Int)`-kinded generic params (`Array(Int, N)` sizes), but only for **literal** values — `Array(Int, 3)` works, `Array(Int, computeSize())` doesn't. That ceiling is already baked into the AST/checker types from #66/#71: - `GenericArg::Value` holds a `Spanned<Literal>`, not a `Spanned<Expr>`. - `InstantiationArg::Value` holds a `Literal`, not a resolved comptime result. - `check_array_size` explicitly skips non-literal sizes, since `Scope` only tracks `Ty`, not values. To support arbitrary comptime-evaluated expressions in `Comptime(_)` position, we need an actual comptime evaluator — not just a checker tweak. Open design questions for whoever picks this up: - **What counts as comptime-evaluable?** Literals and arithmetic on them, obviously. Named consts (`let N = 3; Array(Int, N)`)? Calls to other functions, if those functions are themselves comptime-pure (Zig-style comptime-ness tracked through the call graph)? - **AST change:** `GenericArg::Value` would need to hold a `Spanned<Expr>` instead of a `Literal`, with the checker reducing it to a `Literal`/concrete value or failing with a diagnostic. - **Where does evaluation live?** Something like `check_comptime_expr` alongside `check_expr`, needing `Scope` (or a sibling) to track actual bound values, not just types. - **Memoization:** presumably a salsa-tracked query, so `computeSize()` isn't re-evaluated on every reference. - **Failure mode:** a new diagnostic for comptime-eval failure (calls something non-const, etc.), distinct from `InvalidArraySize`. No implementation yet — this is a design/risk issue, same shape as #69.
jacksonopp added this to the twill project 2026-10-04 01:13:43 +00:00
Author
Owner

Cross-reference: macros (docs/syntax-notes.md's Macros section) are the same underlying problem — a macro is fn @name(...) -> Expr { ... }, an ordinary function that runs at compile time and returns a real Expr value to splice in. Whatever evaluator this issue builds for Comptime(_)-kinded generic params (running a Twill expression at compile time to get a concrete value) is the same kind of machine macro expansion will eventually need.

Not merging the two now, though — docs/project-plan.md explicitly lists 'Macro splice syntax + hygiene' under 'Deferred/open (not blocking the numbered steps)', so full macro-execution semantics are intentionally out of scope for the roadmap right now. Keep this issue's evaluator narrow (just enough for Comptime(_) sizes), but worth designing it loosely compatible with eventually being reused for macro bodies, rather than hard-coding assumptions that only hold for integer sizes.

Not spinning this into its own milestone for now, for the same reason — that would mean scoping up to a general-purpose comptime evaluator ahead of where the project plan currently wants to be. Revisit milestone-worthiness once macro splicing actually gets scheduled.

Cross-reference: macros (`docs/syntax-notes.md`'s Macros section) are the same underlying problem — a macro is `fn @name(...) -> Expr { ... }`, an ordinary function that runs at compile time and returns a real `Expr` value to splice in. Whatever evaluator this issue builds for `Comptime(_)`-kinded generic params (running a Twill expression at compile time to get a concrete value) is the same *kind* of machine macro expansion will eventually need. Not merging the two now, though — `docs/project-plan.md` explicitly lists 'Macro splice syntax + hygiene' under 'Deferred/open (not blocking the numbered steps)', so full macro-execution semantics are intentionally out of scope for the roadmap right now. Keep this issue's evaluator narrow (just enough for `Comptime(_)` sizes), but worth designing it loosely compatible with eventually being reused for macro bodies, rather than hard-coding assumptions that only hold for integer sizes. Not spinning this into its own milestone for now, for the same reason — that would mean scoping up to a general-purpose comptime evaluator ahead of where the project plan currently wants to be. Revisit milestone-worthiness once macro splicing actually gets scheduled.
jacksonopp removed this from the twill project 2026-10-04 02:27:37 +00:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jacksonopp/twill#76
No description provided.