Skip to content

CTFE-restriction enforcement #190

@0xGeorgii

Description

@0xGeorgii
fn make_arr() -> [i32; 3] { return [10, 20, 30]; }
  pub fn sum() -> i32 {
      const ARR: [i32; 3] = make_arr();   // ALLOWED today
      return ARR[0] + ARR[1] + ARR[2];
  }

This compiles, runs, and is the const_sret_call fixture. The const keyword here means "name + immutability" — it does NOT mean "compile-time evaluable". So const X = some_fn() semantically over-promises — users coming from Rust will assume it's compile-time evaluated and try to use it at top level, in array sizes, etc.

The three options for fixing this divergence:

Option A — restrict const to CTFE only

  • Add analysis rule that walks every const initializer. Rejects FunctionCall, Identifier resolving to let/parameter, ArrayIndexAccess, Uzumaki.
  • Allows: number/bool literals, arithmetic on literals, Identifier resolving to another const, struct/array literals composed of CTFE expressions, enum tag access.
  • Cost: Inference becomes Rust-aligned. The const_sret_call.inf and const_compound_copy.inf fixtures we just shipped become invalid — they'd fail A033. Both must migrate to let. byte-identity test's arr_sret_sum, struct_sret_x, arr_copy_first, struct_copy_x sub-fixtures also need migration.
  • Benefit: No new keyword. Single mental model: const = compile-time. Matches Rust intuition.

Option B — add new comptime const keyword (or similar).

  • Existing const keeps Zig semantics; A033 doesn't fire on it.
  • New keyword (e.g., comptime const X = ...) is CTFE-restricted.
  • Cost: Larger surface. Tree-sitter grammar update, AST builder changes, new Stmt::ComptimeConstDef variant or a flag on ConstDef, new keyword tokenization, type-checker awareness, codegen pass-through.
  • Benefit: Doesn't break the current design. Both the lax and the strict semantics are available. Clean migration path: write comptime const when you want CTFE; write const when you want the immutable-let alias.

Option C — opt-in CTFE check via attribute.

  • #[ctfe] const X = ...; triggers A033 only on attributed consts.
  • Cost: Inference doesn't have attribute syntax today. This means designing and implementing an attribute system from scratch (parser, AST, semantic resolution) just for this one rule.
    Significant surface change unless attributes are needed for other things too.
  • Benefit: Smallest semantic change. No new keyword, no rule reversal. But the implementation cost is by far the largest of the three.

Metadata

Metadata

Assignees

No one assigned

    Labels

    static analysisStatic code analysissyntaxInference syntax related

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions