Skip to content

fix(members): credit interface-typed property dispatch through implementers (#1863)#1889

Merged
BartWaardenburg merged 1 commit into
mainfrom
fix/issue-1863-interface-property-dispatch
Jul 14, 2026
Merged

fix(members): credit interface-typed property dispatch through implementers (#1863)#1889
BartWaardenburg merged 1 commit into
mainfrom
fix/issue-1863-interface-property-dispatch

Conversation

@BartWaardenburg

Copy link
Copy Markdown
Collaborator

unused-class-members false-flagged a method reached through a property whose declared type is an interface, on a class that implements that interface (ports-and-adapters / hexagonal DI): useIt(deps: Deps) { deps.greeter.greet() } where Deps.greeter: GreeterPort and class GreeterAdapter implements GreeterPort. The interface dispatch already worked through a direct parameter or variable; this closes the remaining gap where the receiver is reached via an interface property hop.

The #1785 typed-property hop resolves the terminal to interface GreeterPort, but the terminal credit only handled classes (export_is_class_with_members gates out interfaces), so it never reached the interface-to-implementer propagation that already covers the direct-parameter case. propagate_typed_property_accesses now routes an interface terminal to its canonical export key so the later propagate_interface_member_accesses pass carries the member to every implementing class.

Additive and false-negative-only (can only suppress a false positive, never create one). Analyze-only, so no CACHE_VERSION bump. A genuinely-unused method on the implementing class still reports.

Third in the #1785 / #1788 / #1858 cluster. Thanks @lukeramsden for the clean minimal reduction.

Closes #1863

…enters (#1863)

A method reached through a property whose declared type is an interface, on a class that implements that interface (deps.greeter.greet() where Deps.greeter: GreeterPort and GreeterAdapter implements GreeterPort), was false-flagged as unused-class-member. The #1785 typed-property hop resolves the terminal to the interface, but the terminal credit only handled classes (export_is_class_with_members gates out interfaces), so it never reached the interface-to-implementer propagation that already covers the direct-parameter case (useIt(g: GreeterPort) { g.greet() }).

propagate_typed_property_accesses now routes an interface terminal to its canonical export key so the later propagate_interface_member_accesses pass carries the member to every implementing class, making the property-hop terminal behave exactly like the direct-parameter case. Additive and false-negative-only: a terminal that is not an interface with implementers credits nothing, so it can only suppress a false positive, never create one. No CACHE_VERSION bump (analyze-only; reads existing type_member_types facts and class_heritage.implements).

Closes #1863
@BartWaardenburg BartWaardenburg merged commit a3f68d3 into main Jul 14, 2026
19 of 20 checks passed
@BartWaardenburg BartWaardenburg deleted the fix/issue-1863-interface-property-dispatch branch July 14, 2026 14:38
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.

unused-class-members: interface-typed property dispatch loses credit (ports-and-adapters DI)

1 participant