Skip to content

fix(codegen-deno): don't re-declare preamble Option/Result constructors#606

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/fix-deno-dup-constructors
Jun 20, 2026
Merged

fix(codegen-deno): don't re-declare preamble Option/Result constructors#606
hyperpolymath merged 1 commit into
mainfrom
claude/fix-deno-dup-constructors

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Deno-ESM: stop re-declaring the preamble's Option/Result constructors

The locally-declared sibling of the duplicate-constructor bug fixed in #604.

Bug

The Deno-ESM runtime preamble always declares Some/None/Ok/Err. gen_type_decl also emits them for any program that declares type Option/type Result — including stdlib/prelude.affine — so the emitted module crashes under node:

$ affinescript compile --deno-esm -o prelude.deno.js stdlib/prelude.affine
$ node prelude.deno.js
SyntaxError: Identifier 'Some' has already been declared

It stayed latent because the #136 AOT smoke only checks the emitted module is non-empty — it never runs it.

Fix

Skip the variants the preamble already provides (Some/None/Ok/Err) when lowering a TyEnum in codegen_deno.ml. User-defined enums are unaffected.

Verified

stdlib/prelude.affine -> deno : `const Some` ×1, runs under node ✅ (was ×2, crashed)
user enum (Color=Red|Green|Blue): still emitted, runs ✅
tools/run_codegen_deno_tests.sh : all harnesses pass under node ✅
dune test : 459 green (+1 new regression test)

New test Deno-ESM no duplicate Option/Result constructor asserts const Some is declared exactly once — the run-under-node guard the AOT smoke lacked.

Scope / follow-ups

🤖 Generated with Claude Code

https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8


Generated by Claude Code

The Deno-ESM runtime preamble already declares Some/None/Ok/Err. gen_type_decl
re-emitted them for any program that DECLARES `type Option`/`type Result`
(e.g. stdlib/prelude.affine), so the emitted module crashed under node with
`SyntaxError: Identifier 'Some' has already been declared`. The #136 AOT smoke
never caught it — it only checks the emitted module is non-empty, never runs it.

Skip the variants the preamble already provides (Some/None/Ok/Err) when
lowering a TyEnum; user-defined enums are unaffected. Add a regression test
asserting `const Some` is declared exactly once.

This is the locally-declared sibling of the imported-constructor duplication
fixed in #604; together they close the duplicate-constructor class on the
Deno-ESM backend.

Verified: stdlib/prelude.affine now runs under node; dune test 459 green;
tools/run_codegen_deno_tests.sh all harnesses pass under node. The JS and C
backends share the same latent preamble/declaration duplication (not executed
in CI); tracked separately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8
@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 hyperpolymath marked this pull request as ready for review June 20, 2026 19:19
@hyperpolymath hyperpolymath merged commit 2efe0e3 into main Jun 20, 2026
16 checks passed
@hyperpolymath hyperpolymath deleted the claude/fix-deno-dup-constructors branch June 20, 2026 19:20
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