Skip to content

feat(parser): CORE-01 pt2 — &mut e exclusive-borrow surface (zero conflict delta)#269

Merged
hyperpolymath merged 1 commit into
mainfrom
core01-pt2-parser-surface
May 19, 2026
Merged

feat(parser): CORE-01 pt2 — &mut e exclusive-borrow surface (zero conflict delta)#269
hyperpolymath merged 1 commit into
mainfrom
core01-pt2-parser-surface

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

CORE-01 pt2 — &mut e exclusive-borrow parser surface

Refs #177 (not Closes — the NLL/outer=&x analysis remains; it is
now expressible, no longer parser-gated).

Why

pt1 (#240) shipped shared-XOR-exclusive (UseWhileExclusivelyBorrowed,
ConflictingBorrow) but those rules could never fire from real
source
: &mut e did not parse — only shared &e (OpRef) existed.
The pt2 residual was parser-gated. This adds the missing surface.

Change

File What
ast.ml new unary_op OpMutRef (&mut e) — borrow-checker-only distinction
parser.mly expr_unary | AMP MUT e before AMP ezero conflict delta (21 S/R + 1 R/R baseline held; AMP MUT unambiguous)
borrow.ml OpMutRefExclusive borrow (the soundness payload); ref_target/is_copy match it
typecheck.ml / codegen.ml OpMutRef folded into OpRef (typed TRef, same pointer codegen); gen_unop exhaustive

Verified

  • &mut x parses ✓
  • two &mut xConflictingBorrow ✓ (previously unrepresentable)
  • read x while &mut x live → UseWhileExclusivelyBorrowed
  • return &mut localBorrowOutlivesOwner ✓ (composes with pt2 return-escape)
  • shared &x unchanged ✓; &mut x emits wasm (177 B) ✓
  • Full gate 278 → 281 (+3 hermetic tests + 3 fixtures); all stdlib
    AOT green — zero over-rejection

Scope (honest)

&-in-#{ literals and bare block-statements already parse on main.
The -> &T/&T type sigil is deliberately not addedref T/
mut T keyword types already express reference types; a &T sigil would
be duplicate surface (ADR territory, not a soundness gap). The pt2
residual is now the NLL / outer = &x dataflow analysis — now
expressible (surface unblocked), no longer parser-gated. Ledger +
in-code comment truthed.

🤖 Generated with Claude Code

The pt2 residual was parser-gated: the shared-XOR-exclusive rules from
pt1 (#240 UseWhileExclusivelyBorrowed / ConflictingBorrow) could never
fire from real source because `&mut e` did not parse — only shared `&e`
(OpRef) existed. This adds the exclusive-borrow expression surface.

- ast.ml: new `unary_op` variant `OpMutRef` (`&mut e`). Documented: only
  the borrow checker distinguishes it from `OpRef`; every other backend
  treats `&mut e` exactly like `&e` (a reference is the same runtime
  pointer — exclusivity is a static property).
- parser.mly: `expr_unary | AMP MUT e -> ExprUnary (OpMutRef, e)`,
  ordered before `AMP e`. `AMP MUT` is unambiguous (an expression cannot
  begin with the MUT keyword) — **zero Menhir conflict delta**: 21 S/R
  states + 1 R/R + 68/7 arbitrarily-resolved baseline held (ADR-012).
- borrow.ml: `OpMutRef` => *Exclusive* borrow (vs `OpRef` Shared);
  `ref_target`/`is_copy` also match it. This is the soundness payload.
- typecheck/codegen: `OpMutRef` folded into the `OpRef` arm (typed
  `TRef`, same heap-pointer codegen); `gen_unop` made exhaustive.

Verified: `&mut x` parses; two `&mut x` => ConflictingBorrow; read `x`
while `&mut x` live => UseWhileExclusivelyBorrowed; `return &mut local`
=> BorrowOutlivesOwner (composes with pt2 return-escape); shared `&x`
unchanged; `&mut x` emits wasm (177 B). Full gate 278 -> 281 (+3
hermetic "E2E Borrow Graph" tests + 3 fixtures); all stdlib AOT green —
zero over-rejection.

Scope: `&`-in-`#{` literals + bare block-statements already parse on
main; the `-> &T`/`&T` *type* sigil is deliberately NOT added (`ref T`/
`mut T` keyword types already express reference types — a `&T` sigil is
duplicate surface, ADR territory, not a soundness gap). The pt2 residual
is now the NLL/`outer=&x` *analysis* (expressible, no longer
parser-gated), not surface. Ledger + borrow.ml comment truthed.
Refs #177 (not Closes — NLL analysis remains).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 47 issues detected

Severity Count
🔴 Critical 12
🟠 High 21
🟡 Medium 14

⚠️ Action Required: Critical security issues found!

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@v4 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 hyperpolymath merged commit ec19653 into main May 19, 2026
15 of 16 checks passed
@hyperpolymath hyperpolymath deleted the core01-pt2-parser-surface branch May 19, 2026 18:54
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.

1 participant