Skip to content

[move][move-decompiler] Inline immutable aliases to remove additional lets [1/8]#26803

Merged
cgswords merged 3 commits into
mainfrom
cgswords/decomp-simple-refine-2-inline-immutable-alias
Jun 8, 2026
Merged

[move][move-decompiler] Inline immutable aliases to remove additional lets [1/8]#26803
cgswords merged 3 commits into
mainfrom
cgswords/decomp-simple-refine-2-inline-immutable-alias

Conversation

@cgswords

Copy link
Copy Markdown
Contributor

Description

Rename the single-use binding inliner to inline_immutable_alias and generalize its logic to inline any let x = y; whose source y is never mutated, not only single-use ones. This eliminates more redundant let bindings 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.

  • Protocol:
  • Nodes (Validators and Full nodes):
  • gRPC:
  • JSON-RPC:
  • GraphQL:
  • CLI:
  • Rust SDK:
  • Indexing Framework:

@cgswords cgswords requested a review from tzakian May 28, 2026 08:05
@vercel

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sui-docs Ready Ready Preview, Comment Jun 8, 2026 8:58pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
multisig-toolkit Ignored Ignored Preview Jun 8, 2026 8:58pm
sui-kiosk Ignored Ignored Preview Jun 8, 2026 8:58pm

Request Review

@tzakian tzakian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A.m.a.z.i.n.g!

@cgswords cgswords deleted the branch main June 8, 2026 20:50
@cgswords cgswords closed this Jun 8, 2026
@cgswords cgswords reopened this Jun 8, 2026
@cgswords cgswords temporarily deployed to sui-typescript-aws-kms-test-env June 8, 2026 20:52 — with GitHub Actions Inactive
@cgswords cgswords changed the base branch from cgswords/decomp-simple-refine-1-simplify-borrow-deref to main June 8, 2026 20:52
cgswords added 3 commits June 8, 2026 13:53
…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.
@cgswords cgswords force-pushed the cgswords/decomp-simple-refine-2-inline-immutable-alias branch from f560314 to e96cffc Compare June 8, 2026 20:53
@cgswords cgswords temporarily deployed to sui-typescript-aws-kms-test-env June 8, 2026 20:53 — with GitHub Actions Inactive
@cgswords cgswords merged commit afbb508 into main Jun 8, 2026
66 of 69 checks passed
@cgswords cgswords deleted the cgswords/decomp-simple-refine-2-inline-immutable-alias branch June 8, 2026 21:22
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.

2 participants