You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
codegen: perry_method_<Class>__<name> emission order is HashMap-nondeterministic when a method name is shared across classes (#7038/#7039 family) #7172
Found during PR #7171's IR-neutrality verification (macOS arm64, same-compiler control runs): emitted LLVM IR is nondeterministic when a method name is shared across classes — perry_method_<Class>__<name> symbols are emitted in HashMap iteration order, so two runs of the same compiler on the same source produce differently-ordered IR.
Observed on real dependency files: vite's module-runner.js and rollup's shared/index.js (the two corpus files excluded as control-failed in #7171's 47/0/2 IR comparison — reported honestly as control failures, not counted as passing).
Class
Same family as #7038/#7039 (closure-source HashMap iteration made @.str.N numbering a per-process permutation on macOS — fixed by sorting) and #7131 (Linux temp names — fixed). This is the method-emission sibling: cross-class shared method names iterate an unordered map.
Why it matters
Any object-hash or IR-diff A/B silently excludes affected files (or worse, reads phantom diffs) — two agents have now had to build control-run machinery to detect it.
Compile vite/dist/node/module-runner.js (or rollup shared/index.js) twice with the same compiler, --trace llvm or --no-link, diff the IR: method-symbol ordering differs run-to-run.
Closing — fixed by c413af072 (PR #7625, "make emitted IR run-to-run deterministic").
It sorts the ctx.class_ids iteration in lower_call/property_get/dynamic_dispatch.rs (dispatch_roots.sort_unstable_by(|a,b| a.1.cmp(&b.1).then_with(|| a.0.cmp(&b.0)))) and sorts method_registry.rs's class_table walk that builds the (class, method) → perry_method_* symbol map — the exact map this issue names.
The commit reproduces this issue's symptom verbatim: "the same source compiled twice by the same binary emitted the same arms naming DIFFERENT perry_method_* callees per position."
Backed by sabotage-tested coverage in codegen/emission_order_tests.rs and a 126-program zero-diff A/B in changelog.d/7625-codegen-determinism.md — which matters here more than usual, since nondeterminism is precisely the class of bug that a single passing run cannot rule out.
Activity
proggeramlug commentedon Aug 9, 2026
Closing — fixed by
c413af072(PR #7625, "make emitted IR run-to-run deterministic").It sorts the
ctx.class_idsiteration inlower_call/property_get/dynamic_dispatch.rs(dispatch_roots.sort_unstable_by(|a,b| a.1.cmp(&b.1).then_with(|| a.0.cmp(&b.0)))) and sortsmethod_registry.rs'sclass_tablewalk that builds the(class, method) → perry_method_*symbol map — the exact map this issue names.The commit reproduces this issue's symptom verbatim: "the same source compiled twice by the same binary emitted the same arms naming DIFFERENT
perry_method_*callees per position."Backed by sabotage-tested coverage in
codegen/emission_order_tests.rsand a 126-program zero-diff A/B inchangelog.d/7625-codegen-determinism.md— which matters here more than usual, since nondeterminism is precisely the class of bug that a single passing run cannot rule out.