lang F1 2.7: pack-as-value diagnostics (Phase 2 complete)

Using a bare pack name where a runtime value is required was silent garbage
(f(xs)/return xs produced a stray pointer). Now a clear, context-tailored
compile error: isPackName + diagPackAsValue, caught at lowerVarDecl (storage),
lowerReturn (return), lowerFor (iterate), and an identifier-arm catch-all for
call/other. Storage binds a placeholder so there is no cascade error.

Suggestions point at WORKING fixes -- materialize (..xs), or declare the slice
form ..xs: []P for runtime use. The plan category-B "spread ..xs" is broken
(spreading a comptime pack into a []Any param crashes the LLVM verifier; filed
issue 0053), so the diagnostics steer to the slice-of-protocol variadic instead.

Repurposed examples/162-pack-bare-args.sx (was an aspirational bare-$args->[]Any
auto-materialise, contradicting Decision 1) into the slice-form forward
(..args: []Any). examples/203 is the four-category negative test. specs.md "Pack
as value" updated. 238 examples + unit green.
This commit is contained in:
agra
2026-05-30 02:09:41 +03:00
parent ab572359ae
commit 8a875d354c
7 changed files with 197 additions and 20 deletions

View File

@@ -1068,13 +1068,23 @@ changes.
#### Pack as value
Because a pack has no runtime representation, any expression of pack type in a
value-requiring position is a compile error with a tailored suggestion:
Because a pack has no runtime representation, using the **bare pack name** where
a runtime value is required is a compile error with a context-tailored
suggestion:
- storing/binding it (`let x = xs;`, `self.f = xs;`) → suggest `(..xs)`;
- passing to a non-pack-taking call (`f(xs)`) → suggest `..xs`;
- returning it (`return xs;`) → suggest a tuple return with `(..xs)`;
- iterating at runtime (`for xs : (x)`, `xs[runtime_i]`) → suggest `inline for`.
- storing/binding it (`x := xs;`, `self.f = xs;`) → materialize a tuple `(..xs)`;
- passing it to a runtime call (`f(xs)`) → declare the parameter as a *slice*
variadic `..xs: []P` (a runtime slice) instead of a pack `..xs: P`;
- returning it (`return xs;`) → return a tuple `(..xs)` (and make the return
type that tuple);
- iterating it (`for xs : (x)`, `xs[runtime_i]`) → `inline for 0..xs.len (i)`
for a comptime unroll, or take `..xs: []P` for a runtime loop.
The recurring runtime escape hatch is the **slice-of-protocol variadic**
`..xs: []P` (see "Variadic Functions"): it is the runtime, protocol-erased
counterpart to the comptime pack. A pack indexed/iterated/forwarded at runtime
is almost always better expressed by declaring `xs` as `..xs: []P` in the first
place.
#### Storage and protocol conformance