feat(stdlib): STDLIB-04a — Mut effect externs (make_ref/get/set) → real impl (Closes #328)#334
Merged
Merged
Conversation
… impl (Closes #328) The `Mut` effect externs declared in `stdlib/effects.affine` were stubs: the surface parsed but no backend wired the runtime semantics, so any caller would compile and then fail with "make_ref is not defined" at runtime. This lands the real implementations. * interp.ml — `make_ref` allocates a `VMut` cell; `get`/`set` route through the existing cell deref/assign primitives (same store used by the borrow-surface `&mut`). * codegen_deno.ml — lowers to a single-field `{__cell: x}` object so `get`/`set` are O(1) field access; `set` is a comma-expression returning `null` to match the `Unit` signature. * test_e2e.ml — 3 hermetic tests under "E2E STDLIB-04a Mut #328": Int round-trip, String round-trip (value-polymorphic), and a Deno-codegen assertion that the emitted JS contains `__cell` (proves the new builtin-table entries actually fire). These are runtime mutable cells (`Ref<T>` parameterised type), distinct from the borrow-checker `&`/`&mut` references — different concept that happens to share the word "ref". Updates `docs/TECH-DEBT.adoc` row 04a to DONE per the audit-split contract (Refs #175). Closes #328. Refs #175.
🔍 Hypatia Security ScanFindings: 143 issues detected
View findings[
{
"reason": "Stray AI.a2ml in root -- use 0-AI-MANIFEST.a2ml only",
"type": "banned",
"file": "AI.a2ml",
"action": "delete",
"rule_module": "root_hygiene",
"severity": "high"
},
{
"reason": "Superseded by 0-AI-MANIFEST.a2ml",
"type": "banned",
"file": "AI.djot",
"action": "delete",
"rule_module": "root_hygiene",
"severity": "high"
},
{
"reason": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action actions/checkout@v6 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"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": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/example/smoke_driver.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/cli.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/affinescript/affinescript/affinescript-deno-test/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
pushed a commit
that referenced
this pull request
May 24, 2026
Reconciles PR #336 (CORE-02 / #234 / ADR-016 truth ledger to DELIVERED) with two intervening main commits: f45afa1 feat(borrow): NLL last-use expiry for ref-bindings (CORE-01 pt3 Slice A, Refs #177) (#335) 99ae5e3 feat(stdlib): STDLIB-04a — Mut effect externs (make_ref/get/set) → real impl (Closes #328) (#334) Single conflict, docs/TECH-DEBT.adoc — HEAD updated CORE-02 (now CLOSED 2026-05-19 with full ADR-016 S1..S4 narrative); origin/main (#335) updated CORE-01 (Part 3 Slice A NLL last-use expiry LANDED). Independent adjacent rows; resolution takes both — neither side loses information. The PR's comment edits in lib/codegen.ml, lib/effect_sites.ml, lib/typecheck.ml, and the test/test_main.ml suite-label change all survive intact through the merge. Pure documentation + merge content. Zero behavioural risk.
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.
Summary
Lands real implementations of the three
Muteffect externs declared instdlib/effects.affine:Before this PR they were stubs — the surface parsed and typechecked, but no backend wired the runtime semantics, so any caller would compile and then fail at runtime with
make_ref is not defined.Changes
lib/interp.ml— three newVBuiltinentries:make_refallocates aVMutcell (the existing runtime mutable-cell variant inValue);get/setroute through the standard deref / assign primitives. Reuses the same store the borrow-surface&mutalready uses.lib/codegen_deno.ml— three new entries indeno_builtins:make_ref→{__cell: x},get→((r).__cell),set→(((r).__cell = x), null). Single-field object soget/setare O(1);setreturnsnull(Unit) via comma-expression to match the signature.test/test_e2e.ml— three hermetic tests underE2E STDLIB-04a Mut #328:make_ref(7); set(r, 42); get(r) == 42make_ref("alpha"); set(r, "omega"); get(r) == "omega"__cellshape (proves the new table entries actually fire).docs/TECH-DEBT.adoc— row 04a marked DONE per the audit-split contract from docs(tech-debt): split STDLIB-04 into 04a–04e per per-extern audit (Refs #175) #333.Conceptual note
These are runtime mutable cells (
Ref<T>parameterised type), distinct from the borrow-checker's&/&mutreferences — different concept that happens to share the word "ref". TheMuteffect on the signatures is what marks the call sites as observably stateful.Test plan
E2E STDLIB-04a Mut #328)dune runtestgreen (gate moves from 281 → 284).mdintroducedCloses #328. Refs #175.
Generated by Claude Code