Skip to content

a comptime fn cannot build a List, so a pure List-taking builtin is unreachable at comptime (wolf-std F-0077) #101

Description

@mfwolffe

wolf-std F-0077. Measured at wolf-lang trunk 4e316ad, both compiler rungs, --checked and --native agreeing.

A comptime fn cannot build a List:

comptime fn probe() -> int { var k = 0  k = k + 3  k }         run
comptime fn probe() -> int { let s = "hi"  s.len }             run
comptime fn probe() -> int { miss(3) else 0 }                  run
comptime fn probe() -> int { let b = List[int]()  b.len }      unsupported @resolve
comptime fn probe() -> int { str_from_utf8(List[int]()) … }    unsupported @resolve

The record carries no code and no reason string (the F-0051 silence), so this needed a bisect rather than a reading: the first three lines are what rule out the var, the str, the else and the row, and the last two are what identify the List.

The consequence is a rule, not an inconvenience: a pure builtin whose argument is a List is unreachable at comptime, whatever the sandbox thinks. s81's str_from_utf8 is the first such builtin. It carries no I13 capability and no sandbox category — D33 has nothing to say about it, exactly as intended — and it still cannot be called from a comptime fn, because a List is the only way to spell its argument.

That matters to wolf-std beyond one function. std.bytes.to_str's doc now has to read "the D33 sandbox has no objection and the engine cannot get there anyway", which is a sentence a reader has to be given, because every other signal points the other way: no capability note, no E0701, and a doc convention (§14) that spells out comptime-safety for pure members of otherwise-effectful modules. The alternative was to write "pure and comptime-safe" and be wrong in a way no test in that repository would have caught.

Two asks, in order of preference:

  1. List construction and element access inside the comptime engine (s16's own scope). A comptime program that can build no container cannot do the work CTFE exists for — table generation, in particular.
  2. Failing that, a NAMED refusal, so a package author learns which subset they left. This is the third caller for that half: F-0060 (json builtins refused at comptime with a bare unsupported, no diagnostic) and F-0069 (? inside a comptime fn is unsupported, and it masks the capability refusal so a D33 rejection test silently proves nothing) asked for it first. A permanent check (the sandbox) losing to a temporary one (the engine's subset), silently, is the pattern all three share.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions