Skip to content

fix(hir): static method calls + static field get/set must resolve scope-local class renames#5969

Merged
proggeramlug merged 2 commits into
mainfrom
fix/renamed-class-static-dispatch
Jul 4, 2026
Merged

fix(hir): static method calls + static field get/set must resolve scope-local class renames#5969
proggeramlug merged 2 commits into
mainfrom
fix/renamed-class-static-dispatch

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Fixes the red acceptance test on main (same_class_name_across_factories_keeps_snapshots_separate, from #5938): a body-local class X colliding with an outer/prior class X registers under a scope-local rename (class_renames), and bare-ident references + new X() already resolve it — but the static-METHOD-call arm (expr_call/static_and_instance.rs, both Ident and #private arms) and the static-FIELD get/set arms (expr_member.rs, expr_assign.rs, lower_expr/assignment.rs) looked up the raw name, binding the FIRST same-named registrant. Factory B's e.who() dispatched to factory A's static and read A's capture snapshot ('B: alpha' instead of 'B: beta1').

All four arms now resolve the rename before the class lookups; imports keep the raw name (a renamed class is body-local by construction, never imported).

  • Adds renamed_class_statics_dispatch_to_renamed_registrant (static calls + static field read/write + construction across two factories, node-validated).
  • Full sweep of the class/static/capture/5437/w6 e2e suites + perry-hir units: zero failures.

Note per #5960: the PR cargo-test gate runs unit tests only, so the failing acceptance suite rode in invisibly with #5938 — verified locally at the #5938 squash commit and at the pre-rebase tree (fails both), and green with this fix.

Code-only; metadata folded at merge.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed static member reads, writes, and method calls to use the scope-resolved class name, ensuring correct binding when class names collide or are renamed.
    • Improved related assignment and member dispatch behavior so static operations target the intended class registrant across factories.
  • Tests

    • Added a regression test covering renamed/colliding classes to verify static method calls, static field get/set, and instance construction behavior remain consistent.
  • Chores

    • Bumped the workspace version and updated the changelog entry for this fix.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e61a1ac0-0056-48ee-887c-89fc79ca0a12

📥 Commits

Reviewing files that changed from the base of the PR and between 51ddb9d and 0d02e7d.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • CHANGELOG.md
  • CLAUDE.md
  • Cargo.toml
  • crates/perry-hir/src/lower/expr_assign.rs
  • crates/perry-hir/src/lower/expr_call/static_and_instance.rs
  • crates/perry-hir/src/lower/expr_member.rs
  • crates/perry-hir/src/lower/lower_expr/assignment.rs
  • crates/perry/tests/capture_rereg_renamed_class.rs

📝 Walkthrough

Walkthrough

Static member lowering now resolves scope-local class renames before class, field, and method lookups, and a regression test covers colliding class bindings. Release metadata was bumped to v0.5.1235.

Changes

Resolve renamed classes for static member access

Layer / File(s) Summary
Static field get/set resolves renamed class
crates/perry-hir/src/lower/expr_assign.rs, crates/perry-hir/src/lower/lower_expr/assignment.rs, crates/perry-hir/src/lower/expr_member.rs
Static field assignment and access lowering compute a resolved class name via ctx.resolve_class_name before class and field lookups and use it for emitted StaticFieldSet and StaticFieldGet class names.
Static method call dispatch resolves renamed class
crates/perry-hir/src/lower/expr_call/static_and_instance.rs
try_static_method_and_instance resolves the candidate class name before the eligibility gate and uses it for has_static_method checks and the emitted StaticMethodCall class name for public and private static methods.
Regression test and release metadata
crates/perry/tests/capture_rereg_renamed_class.rs, CHANGELOG.md, CLAUDE.md, Cargo.toml
A regression test verifies static methods, static fields, and construction on a renamed colliding class, and the changelog and version metadata are updated to v0.5.1235.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • PerryTS/perry#5659: Both PRs modify crates/perry-hir/src/lower/expr_call/static_and_instance.rs static dispatch logic, with different class-selection conditions.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main fix: resolving scope-local class renames for static method calls and static field access.
Description check ✅ Passed The description covers the required summary, changes, related issue, and test verification, with only optional sections omitted.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/renamed-class-static-dispatch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/perry-hir/src/lower/expr_assign.rs (1)

502-536: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Resolve class renames in the ClassName.prototype path. This branch still uses the raw cls_name; a body-local renamed class X can still resolve to the first same-named registrant. Apply ctx.resolve_class_name here before the class lookup / ProtoOwner::Class selection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/perry-hir/src/lower/expr_assign.rs` around lines 502 - 536, The
class-property assignment handling in expr_assign.rs still uses the raw class
name in the ClassName.prototype path, so body-local renamed classes can bind to
the wrong registrant. Update the logic around the member assignment/class lookup
branch to call ctx.resolve_class_name on the object name before doing
ctx.lookup_class and before choosing the ProtoOwner::Class target, matching the
existing static-field rename handling used in the same function.
🧹 Nitpick comments (1)
crates/perry/tests/capture_rereg_renamed_class.rs (1)

186-233: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for the private-static-method arm.

The PR fixes four lookup arms including private static methods (#helper()), but this test only exercises the public static method, static field get/set, and constructor arms. Consider adding a static #helper() call to close out coverage for that arm too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/perry/tests/capture_rereg_renamed_class.rs` around lines 186 - 233,
Add coverage for the private-static-method dispatch path in
renamed_class_statics_dispatch_to_renamed_registrant by extending the test
snippet to include a static private method like `#helper` on the renamed class e
and verify it is invoked correctly. Keep the existing mkA/mkB structure, but
exercise the private static method alongside the current public static method,
static field, and constructor assertions so the renamed registrant lookup arm is
covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/perry-hir/src/lower/expr_assign.rs`:
- Around line 502-536: The class-property assignment handling in expr_assign.rs
still uses the raw class name in the ClassName.prototype path, so body-local
renamed classes can bind to the wrong registrant. Update the logic around the
member assignment/class lookup branch to call ctx.resolve_class_name on the
object name before doing ctx.lookup_class and before choosing the
ProtoOwner::Class target, matching the existing static-field rename handling
used in the same function.

---

Nitpick comments:
In `@crates/perry/tests/capture_rereg_renamed_class.rs`:
- Around line 186-233: Add coverage for the private-static-method dispatch path
in renamed_class_statics_dispatch_to_renamed_registrant by extending the test
snippet to include a static private method like `#helper` on the renamed class e
and verify it is invoked correctly. Keep the existing mkA/mkB structure, but
exercise the private static method alongside the current public static method,
static field, and constructor assertions so the renamed registrant lookup arm is
covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 47ffdc70-125b-4b01-8da3-a551c5c7bad4

📥 Commits

Reviewing files that changed from the base of the PR and between 408a19c and 51ddb9d.

📒 Files selected for processing (5)
  • crates/perry-hir/src/lower/expr_assign.rs
  • crates/perry-hir/src/lower/expr_call/static_and_instance.rs
  • crates/perry-hir/src/lower/expr_member.rs
  • crates/perry-hir/src/lower/lower_expr/assignment.rs
  • crates/perry/tests/capture_rereg_renamed_class.rs

Ralph Küpper added 2 commits July 4, 2026 16:28
…cope-local class renames

A body-local `class X` colliding with an outer/prior `class X` registers
under a scope-local rename (class_renames), and bare-ident references
(ClassRef) and `new X()` already resolve it — but the static-METHOD-call
arm and the static-FIELD get/set arms looked the raw name up directly, so
they bound the FIRST same-named registrant: factory B's `e.who()`
dispatched to factory A's static and read A's capture snapshot
(same_class_name_across_factories_keeps_snapshots_separate red on main:
'B: alpha' instead of 'B: beta1'). Resolve the rename before the class
lookups in all four arms; imports keep the raw name (a renamed class is
body-local by construction, never imported).

Adds renamed_class_statics_dispatch_to_renamed_registrant covering static
calls, static field reads/writes, and construction across two factories.
@proggeramlug proggeramlug force-pushed the fix/renamed-class-static-dispatch branch from 51ddb9d to 0d02e7d Compare July 4, 2026 14:28
@proggeramlug proggeramlug merged commit 645e5f1 into main Jul 4, 2026
@proggeramlug proggeramlug deleted the fix/renamed-class-static-dispatch branch July 4, 2026 14:28
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