void-payloads, multi-pattern arms, and range patterns (match statements)
This commit is contained in:
@@ -504,6 +504,42 @@
|
||||
is not a runtime field type yet, so 21.5 can't declare them, though the no-capture arm
|
||||
form is already wired; and multi-pattern arms (`.a, .b:`) / range patterns
|
||||
|
||||
22.5. `void`-payloads and multi-pattern arms / range patterns in match statements (implemented; see below)
|
||||
- **void-payload variants**: a tagged union may declare a `void`-payload variant
|
||||
(`quit void`). As in Zig, a void field carries no runtime value — it is allowed only on a
|
||||
tagged union (the record-decl check skips the runtime-value requirement for it), contributes
|
||||
nothing to the layout (`size` 0 / `align` 1, so it is never the carrier), and is constructed
|
||||
with the **bare-key** literal `T{ variant }` (no `= value`). Construction stores only the tag;
|
||||
codegen skips the payload store. Matched with a plain no-capture arm (`.quit:`); a capture on a
|
||||
void variant, a `= value` on a void variant, a bare key on a non-void field, and a direct
|
||||
`x.quit` payload read are all diagnosed
|
||||
- **multi-pattern arms**: an arm may list several patterns (`.a, .b:` / `0, 1, 2:`); the AST
|
||||
`Match_Arm` now carries a `patterns` list and the checker ORs their dispatch conditions. A
|
||||
capturing multi-pattern arm over a tagged union is allowed when every listed variant has the
|
||||
same payload type (Zig parity — payloads share the carrier offset, so it is one read);
|
||||
mismatched payload types are a "capture group with incompatible types" error
|
||||
- **range patterns**: a scalar arm may be a range (`0..10:` / `0..=10:`), desugared to
|
||||
`key >= lo and key <(=) hi` (existing `.Ge`/`.Le`/`.Lt`/`.And` HIR); a range pattern on an
|
||||
enum/union subject is rejected
|
||||
- **pointer captures**: `|@cap|` binds a pointer into the subject's payload (mutate in place),
|
||||
reusing the for-loop `@`-capture and `pointer_capture` flag; mutability follows the subject. It
|
||||
requires an addressable subject — verified to need **no lowering/codegen change**: the subject
|
||||
is spilled as `&subject` and captures route through a `Deref` (`lower_location(Deref)` is the
|
||||
pointee address), so `Address(Field(Deref(ptr)))` aliases the original storage
|
||||
- the only new codegen is the void construction skip (one `llvm` site) plus a one-line `lower`
|
||||
guard so a void variant's absent payload operand is not lowered into a trapping recovery value;
|
||||
everything else is parser + checker desugar
|
||||
- deferred (`// ponytail:` follow-ups): contextual void construction (`e Event = .quit`) needs
|
||||
enum-literal→union coercion (milestone 23); Zig `inline .a, .b => |v|` per-tag comptime
|
||||
captures need monomorphization. Separately, a **call expression directly as a match subject**
|
||||
(`match get()`) is a pre-existing gap (assign to a variable first, as the spec examples do);
|
||||
the rvalue pointer-capture guard is defensive for when that lands
|
||||
|
||||
22.6. (`// ponytail:` follow-ups): contextual void construction (`e Event = .quit`) needs
|
||||
enum-literal→union coercion. Separately, a **call expression directly as a match subject**
|
||||
(`match get()`) is a pre-existing gap (assign to a variable first, as the spec examples do);
|
||||
the rvalue pointer-capture guard is defensive for when that lands
|
||||
|
||||
23. error types (see below)
|
||||
|
||||
24. dynamic heap allocation
|
||||
|
||||
Reference in New Issue
Block a user