feat(codegen): infer let mut from assignment analysis (clean rebase of #1460)#1461
Merged
Conversation
Rust requires 'let mut' for locals that are reassigned. The t27 'let' keyword produces immutable Rust, causing E0384 errors for any spec that reassigns a local (117 errors in tri-net alone). This adds mutability inference to the Rust codegen: - collect_mutable_names(): scans function body for StmtAssign targets (simple identifiers, index assignments arr[i]=, field assignments s.f=) - RustCodegen.mut_names: per-function set of names needing mut - Both let-emission sites (gen_fn + gen_rust_stmt) check the set Reproducibility (from ssdm4 macbook, ветка feat/mut-inference-2026-07-13): cargo check --lib in tri-net: 141 errors -> 0 errors, 101 tests pass. cited SHA: 96d3581 (measurement realm) Over-inference (mut on read-only locals) produces warnings, not errors. Note: cleanly cherry-picked from PR #1460 head onto current master (4832ec6). Discards 249 unrelated commits from stacked branch. Also re-seals FROZEN_HASH per M5 ceremony (compiler.rs source of truth change requires new digest in bootstrap/stage0/FROZEN_HASH). Co-Authored-By: ssdm4 <ssdm4@MacBook-Pro.local> phi^2 + phi^-2 = 3
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
This was referenced Jul 13, 2026
gHashTag
marked this pull request as ready for review
July 13, 2026 06:51
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-07-13 07:18:35 UTC
Summary
Seal Status
|
gHashTag
pushed a commit
that referenced
this pull request
Jul 13, 2026
Three surgical fixes to the optimizer that together let mut-inference (PR #1461) actually deliver clean gen/rust on downstream repos: 1. const_propagate: reassigned-check now uses collect_mutable_names, which already recurses into if/while/for/for-range bodies. Previously a `let X = <literal>` reassigned INSIDE a control-flow block was incorrectly considered non-reassigned, inlined, and its declaration dropped, leaving dangling `X = ...` reassignments in emit. 2. copy_propagate: same recursive reassigned-check guard added. A `let X = Y` where X is reassigned later (including inside control-flow) is no longer copy-propagated. 3. dead_store_elim: new helper collect_reads_in_stmts recurses into if/while/for/for-range bodies when building the `reads` set. Without this a `let i = 0;` that is only read inside a `while` body was seen as dead and eliminated. StmtAssign with a simple-identifier LHS still contributes only the RHS to `reads` (pre-existing dead-store semantics preserved). Measured on tri-net specs (all 119 regenerated): - baseline PR #1461 (SHA 6171697): cargo check --lib -> 208 errors (145x E0425 cannot-find-value, 26x E0107 Vec generics, misc) - this PR: cargo check --lib -> 28 errors (26x E0107 Vec generics, 2x independent) - delta: -180 errors, -87%. E0425 -> 0. t27c own tests: 1491 passed / 3 failed. Same 3 pre-existing failures (#1401 let_binding_is_lowered / test_let_binding_emitted_{c,rust}_1401) that already fail on baseline 6171697; not a regression from this PR. FROZEN_HASH re-sealed via bootstrap/stage0 ceremony. Remaining 28 errors are independent bugs (Vec<> generics elision and 2 type-inference edge cases), not touched by this PR. phi^2 + phi^-2 = 3
gHashTag
added a commit
that referenced
this pull request
Jul 13, 2026
…#1465) * feat(codegen): recursive reassignment + read scan in optimizer passes Three surgical fixes to the optimizer that together let mut-inference (PR #1461) actually deliver clean gen/rust on downstream repos: 1. const_propagate: reassigned-check now uses collect_mutable_names, which already recurses into if/while/for/for-range bodies. Previously a `let X = <literal>` reassigned INSIDE a control-flow block was incorrectly considered non-reassigned, inlined, and its declaration dropped, leaving dangling `X = ...` reassignments in emit. 2. copy_propagate: same recursive reassigned-check guard added. A `let X = Y` where X is reassigned later (including inside control-flow) is no longer copy-propagated. 3. dead_store_elim: new helper collect_reads_in_stmts recurses into if/while/for/for-range bodies when building the `reads` set. Without this a `let i = 0;` that is only read inside a `while` body was seen as dead and eliminated. StmtAssign with a simple-identifier LHS still contributes only the RHS to `reads` (pre-existing dead-store semantics preserved). Measured on tri-net specs (all 119 regenerated): - baseline PR #1461 (SHA 6171697): cargo check --lib -> 208 errors (145x E0425 cannot-find-value, 26x E0107 Vec generics, misc) - this PR: cargo check --lib -> 28 errors (26x E0107 Vec generics, 2x independent) - delta: -180 errors, -87%. E0425 -> 0. t27c own tests: 1491 passed / 3 failed. Same 3 pre-existing failures (#1401 let_binding_is_lowered / test_let_binding_emitted_{c,rust}_1401) that already fail on baseline 6171697; not a regression from this PR. FROZEN_HASH re-sealed via bootstrap/stage0 ceremony. Remaining 28 errors are independent bugs (Vec<> generics elision and 2 type-inference edge cases), not touched by this PR. phi^2 + phi^-2 = 3 * docs(NOW): update for recursive optimizer scan PR #1462 (Fixes #1464) phi^2 + phi^-2 = 3 --------- Co-authored-by: Perplexity Computer <agent@perplexity.ai> Co-authored-by: SSD DDD <ssdm4@MacBook-Pro.local>
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.
What
Rust requires
let mutfor locals that are reassigned. The t27letkeyword produces immutable Rust, causing E0384 errors for any spec that reassigns a local.Fixes #1463
How
Mutability inference in the Rust codegen backend:
collect_mutable_names(): scans function body forStmtAssigntargets — simple identifiers (x = ...), index assignments (arr[i] = ...), field assignments (s.f = ...)RustCodegen.mut_names: per-functionHashSet<String>of names needing mutlet-emission sites (gen_fn+gen_rust_stmt) check the set before emittingletvslet mutMeasured impact (tri-net, real cargo verdict)
Over-inference (
let muton read-only locals) produces warnings, not errors — Rust is lenient about unnecessary mut.Files
bootstrap/src/compiler.rs— +62 lines, plusbootstrap/stage0/FROZEN_HASHre-seal.phi^2 + phi^-2 = 3