# 0065 — block-expression body does not parse a destructure decl (`v, e := f();`) > **RESOLVED.** Two fixes landed: > - The braced `defer { … }` body now parses via `parseBlock` (src/parser.zig, > the `kw_defer` arm) instead of `parseExpr`, mirroring `onfail`. Regression: > `examples/1050-errors-defer-block-body.sx` (commit `634cf9b`). > - The general *value-producing block in binding position* fell out of the > trailing-`;` block-value rework: value-position `{ … }` now routes through > the same statement parser as every other block, so a destructure decl (and > any statement form) parses, and the trailing expression is the block's > value. Regression: `examples/0042-basic-block-value-destructure.sx`. ## Symptom A destructure declaration (`v, e := f();`) inside a **block used in expression position** fails to parse with `expected ';'`. Two surfaced forms: - `defer { v, e := f(); ... }` — a `defer` body is parsed via `parseExpr` (so its `{ ... }` is a block-EXPRESSION), and the block-expression statement loop doesn't recognize the `name, name :=` destructure form. - `y := { v, e := f(); v };` — a value-producing block bound to a name. Observed: `error: expected ';'` pointing at the statement *after* the destructure (the parser bails at the `:=` and resyncs). Expected: the destructure parses exactly as it does in a normal statement block (an `if` body, a plain `{ }` statement block, or an `onfail { }` body — all of which use `parseBlock` and handle it fine). This is the same family as the pre-existing "value-producing block body in binding position doesn't parse" note in `current/CHECKPOINT-ERR.md` (E2.4b log). `onfail { }` is unaffected because it parses its body with `parseBlock` (src/parser.zig ~2063); `defer` is affected because it uses `parseExpr` (~2029). ## Reproduction ```sx #import "modules/std.sx"; E :: error { Bad } val :: () -> (s32, !E) { return 5; } f :: () -> !E { defer { v, e := val(); // ← error: expected ';' print("v={}\n", v); } return; } main :: () -> s32 { return 0; } ``` Also reproduces with no `defer`, as a plain value block: ```sx y := { v, e := val(); // ← error: expected ';' v }; ``` ## Investigation prompt The block-expression statement loop (the parser path reached from `parseExpr` when it hits `{` — see `src/parser.zig`, the block-as-value parsing around the `parsePrimary`/`parseBlockExpr` path, distinct from `parseBlock` at ~1931) parses each inner statement but does not run the destructure-decl detection that `parseStmt` does. Find where `parseStmt`/`parseBlock` recognizes the `ident (, ident)+ :=` lookahead and make the block-expression statement loop use the same statement parser (ideally route block-expression bodies through `parseStmt` so every statement form — destructure, var/const decl, etc. — is handled uniformly). For `defer` specifically: the simplest aligned fix is to parse a braced `defer` body with `parseBlock` (like `onfail` does) while keeping the bare-expression form (`defer expr;`) on `parseExpr`. That removes the defer-body manifestation even if the general block-expression path is handled separately. Verification: run the repro above — expect it to compile and run (`exit 0`), with the destructure-bound value usable under an `if !e { … }` guard (ERR E1.8). Add a regression example under `examples/` once fixed. ## Status OPEN. Orthogonal to ERR E1.7/E1.8 — the spec'd cleanup-body absorbers are `catch` / `or ` (both parse fine in a `defer` body), so this does not block the error-handling work. Filed while implementing E1.7.