[move][move-decompiler] Inline immutable aliases to remove additional lets [1/8]#26803
Merged
cgswords merged 3 commits intoJun 8, 2026
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ble_alias`
Rename `inline_single_use_bindings` to `inline_immutable_alias` and relax
the eligibility predicate: a `let X = Y;` binding now fires whenever `Y`
has zero writes (was: exactly one read). `Y`'s value is stable for the
function's lifetime, so substituting it for `X` preserves semantics
regardless of how many places read `Y`.
The destination guard on `X` is unchanged — one defining `LetBind`, no
re-assignment, and (when there are multiple syntactic reads) no path
that reads `X` twice. The latter still matters for non-`copy` types
even though `Y` is immutable: a double substitution would convert a
single move into two reads.
Snapshot impact: the cetus argument-staging idiom
let l40 = l13; let l39 = l12; let l38 = l11;
is_stable(freeze(l0), l38, l39, l40)
now collapses to `is_stable(freeze(l0), l11, l12, l13)`. Similar wins
across `dbke.mv` and the enum-match snapshots.
Four staging let-bindings of immutable parameters `p` and `q` — each of which is used in multiple other staging slots. Old `inline_single_use_bindings` declined (each RHS was read more than once); `inline_immutable_alias` now folds them all to `l0 + l1 + l0 + l1`.
A `let X = Y;` is only safe to inline when slot `Y` is invariant from the binding to each use of `X`. The previous `assigns(Y) == 0` check caught direct reassignment but missed mutation through a `&mut`: a site that takes `&mut Y` (or `&mut X`) hands out a reference through which a `WriteRef` — or a callee receiving the reference — can reassign the slot, invisible to `assigns`. Add a `mut_borrows` counter to `NameCounts` (bumped on `Borrow(true, Variable(n))`) and require `mut_borrows == 0` on both `X` and `Y` in `is_eligible`. Expand the module/`is_eligible` comments with the slot-invariance argument: the check is type-agnostic because pointee mutations (`*Y = e`, `f(Y)`) touch the heap, not the slot, and `X`/`Y` alias the same pointee. Regression test `mut_borrow_blocks_inline`: `let x = 0; let y = x; add_one(&mut x); y` must keep the `let y = x` binding so the function returns the binding-time snapshot (0), not the post-mutation slot (1). Snapshot impact: two staging bindings in cetus that the previous check inlined (`l44`, which is `&mut`-borrowed by `extract_..._coin_send`) are now preserved. The inline happened to be safe there — the mutation precedes the binding — but the slot-level check can't see that ordering; reaching-defs could, and is parked as a follow-up.
f560314 to
e96cffc
Compare
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.
Description
Rename the single-use binding inliner to
inline_immutable_aliasand generalize its logic to inline anylet x = y;whose sourceyis never mutated, not only single-use ones. This eliminates more redundantletbindings for readability, while a mut-borrow guard keeps it from inlining a slot that can be written through a&mut.Test plan
Snapshot updates with new refinements.
Release notes
Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.
For each box you select, include information after the relevant heading that describes the impact of your changes that a user
might notice and any actions they must take to implement updates.