fix(codegen-deno): don't re-declare preamble Option/Result constructors#606
Merged
Conversation
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
🔍 Hypatia Security ScanFindings: 43 issues detected
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_declalso emits them for any program that declarestype Option/type Result— includingstdlib/prelude.affine— so the emitted module crashes under node: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 aTyEnumincodegen_deno.ml. User-defined enums are unaffected.Verified
New test
Deno-ESM no duplicate Option/Result constructorassertsconst Someis declared exactly once — the run-under-node guard the AOT smoke lacked.Scope / follow-ups
Somedecls) but their output isn't executed in CI — tracked as a follow-up, not fixed here.🤖 Generated with Claude Code
https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8
Generated by Claude Code