Skip to content

fix(codegen): support nested patterns inside tuple patterns (WASM)#612

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/wasm-tuple-patterns
Jun 21, 2026
Merged

fix(codegen): support nested patterns inside tuple patterns (WASM)#612
hyperpolymath merged 1 commit into
mainfrom
claude/wasm-tuple-patterns

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Item 3a of the batch — the WASM tuple-pattern half of #607.

Bug

The core-Wasm pattern compiler rejected any tuple sub-pattern that wasn't a bare variable/wildcard:

Codegen.UnsupportedFeature "Only variable and wildcard patterns supported in tuple patterns"

That's the gap stdlib/option.affine and result.affine hit (after #138/#604 got them past the constructor-linking gap).

Fix

gen_pattern's PatTuple case now recurses per element: load element i into a temp local, match it against sub-pattern i, and I32And the per-element test bools. This is stack-safe because every gen_pattern result is one-bool-net with net-zero binds (see PatVar/PatLit/PatCon); binds register through the threaded ctx, exactly like constructor-argument patterns. Literals, constructors, and nested tuples now work as tuple sub-patterns.

Verified (under node)

match (a,b) { (0,y)=>y, (x,0)=>x+100, (x,y)=>x+y }
  classify(0,5)=5  ✓   classify(7,0)=107 ✓   classify(3,4)=7 ✓   (correct arm + binding)

Addresses the tuple-pattern item in #607 (the panic builtin and the mixed-representation match remain).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8


Generated by Claude Code

The core-Wasm backend rejected any tuple sub-pattern that wasn't a plain
variable or wildcard (UnsupportedFeature "Only variable and wildcard patterns
supported in tuple patterns") — which stdlib/option.affine and result.affine
hit. gen_pattern now recurses per tuple element: each element is loaded into a
temp local and matched against its sub-pattern, with the per-element test bools
ANDed together. Every gen_pattern result is one-bool-net with net-zero binds,
so the combination is stack-safe; binds register via the threaded ctx (the same
mechanism constructor-argument patterns use).

Verified under node: `match (a,b) { (0,y)=>y, (x,0)=>x+100, (x,y)=>x+y }`
selects the right arm and binds correctly — (0,5)->5, (7,0)->107, (3,4)->7.
option.affine / result.affine now get PAST this gap (they next hit a separate
`panic`-builtin gap in the Wasm backend, tracked in #607). dune test 461 green;
adds a Wasm nested-tuple regression test.

Part of #607.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8
@hyperpolymath hyperpolymath marked this pull request as ready for review June 21, 2026 00:32
@hyperpolymath hyperpolymath merged commit 0f8e6c5 into main Jun 21, 2026
13 checks passed
@hyperpolymath hyperpolymath deleted the claude/wasm-tuple-patterns branch June 21, 2026 00:32
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 43 issues detected

Severity Count
🔴 Critical 2
🟠 High 25
🟡 Medium 16

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action denoland/setup-deno@v2 needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "scorecard_publish_with_run_step",
    "file": "scorecard-enforcer.yml",
    "action": "split_scorecard_publish_job",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in instant-sync.yml",
    "type": "secret_action_without_presence_gate",
    "file": "instant-sync.yml",
    "action": "peter-evans/repository-dispatch",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
    "type": "js_exec_sync",
    "file": "/home/runner/work/affinescript/affinescript/packages/affinescript-cli/mod.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "Shell execution -- validate input before passing to shell (2 occurrences, CWE-78)",
    "type": "js_exec_sync",
    "file": "/home/runner/work/affinescript/affinescript/packages/affine-vscode/mod.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
    "type": "js_exec_sync",
    "file": "/home/runner/work/affinescript/affinescript/affinescript-vite/src/affine-plugin-improved.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "expect() in hot path (32 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/wasm_gen.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "expect() in hot path (29 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/affine_gen.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unsafe block -- requires SAFETY comment (2 occurrences, CWE-676)",
    "type": "unsafe_block",
    "file": "/home/runner/work/affinescript/affinescript/runtime/src/panic.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unsafe block -- requires SAFETY comment (1 occurrences, CWE-676)",
    "type": "unsafe_block",
    "file": "/home/runner/work/affinescript/affinescript/runtime/src/alloc.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

hyperpolymath added a commit that referenced this pull request Jun 21, 2026
## What

Merges current `main` into `feat/solo-core-metatheory-proofs` and
resolves all conflicts, so that **#614 stops being `mergeable_state:
dirty`**. While #614 is dirty, GitHub cannot build the merge commit, so
its entire CI suite is suppressed (only `lint-workflows` runs). Merging
this PR into the feature branch un-blocks #614's CI.

## Why it was needed

#614 branched off an old `main` (merge-base 61 commits back) and
conflicts with the standalone-CI + codegen work that has since landed
(#602, #603, #604, #606, #609, #610, #611, #612, #613).

## Conflict resolutions (5 files)

| File(s) | Resolution |
|---|---|
| `governance.yml`, `scorecard.yml`, `scorecard-enforcer.yml`,
`hypatia-scan.yml` | Take `main`'s **standalone** versions. The branch
re-adopted the estate `standards` reusables that `main` deliberately
dropped (#603/#604) to stop run-creation `startup_failure`s. `main`'s
`hypatia-scan.yml` also restores the permissions Hypatia needs
(`security-events: write`, `pull-requests: write`, `secrets: inherit`)
and the `MPL-2.0` SPDX id the Palimpsest license doc mandates for
tooling. |
| `docs/PROOF-NEEDS.md` | Drop the branch's stale 103-line `.md`; keep
`main`'s canonical 359-line `.adoc` (#609). Also satisfies DOC-FORMAT. |
| `docs/history/MODULE-SYSTEM-PROGRESS` | Keep the branch's
`.md`→`.adoc` migration; **port** `main`'s additive #138
codegen-follow-up note + status-table row into the `.adoc` so `main`'s
work is preserved. |

`spark-theatre-gate.yml` and `mirror.yml` were identical to `main`.

## Verification (merged tree)

- `dune build` — clean
- `dune test` — **534/534 pass** (incl. `cross-module constructor
linking, Wasm (#138)`, `Wasm nested tuple patterns`, `Deno-ESM / JS no
duplicate Option/Result constructor`)
- wasm-runtime harness (`tools/run_codegen_wasm_tests.sh`) — all pass
- workflow scan — no `startup_failure` risk introduced

## How to use

Merge this into `feat/solo-core-metatheory-proofs`. #614 then becomes
mergeable and its full CI runs.

> Routed via this branch because the environment only permits pushes to
`claude/inspiring-newton-dg5wov`, not directly to the feature branch.

Un-blocks #614.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8

---
_Generated by [Claude
Code](https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8)_

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: hyperpolymath <paraordinate@yahoo.co.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants