Skip to content

Deduplicate implicitly implemented interface methods in member resolution#2711

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:method-signature-duplicated
Jul 20, 2026
Merged

Deduplicate implicitly implemented interface methods in member resolution#2711
lahma merged 1 commit into
sebastienros:mainfrom
lahma:method-signature-duplicated

Conversation

@lahma

@lahma lahma commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Fixes the duplicated candidate signatures reported in #2523 (comment).

Problem

When a member is resolved against a concrete type, TypeResolver.TryFindMemberAccessor collects candidate methods both from the type itself and from every implemented interface. An implicitly implemented interface method is present in both sets, so it was added twice. With ExposeDetailedResolutionErrors enabled a failed call then reported the same signature twice:

No public methods with the specified arguments were found. Target: MyIntefaceImpl.MyMethod; provided arguments: (); candidate signatures: MyMethod(String a), MyMethod(String a)

The duplicate also meant redundant work during overload resolution since both entries bind to the same implementation.

Fix

Interface-sourced (and, for interface targets, object-sourced) methods are now skipped when an earlier candidate already has the same signature. Because class methods are collected first, the class implementation wins, matching C# semantics for a call on the concrete type. The signature comparison is structural:

  • generic methods match across their distinct generic parameter instances (T of the class method vs T of the interface method), including through constructed generics, by-ref and array types
  • genuinely different methods are kept, e.g. an interface method hiding Object.GetHashCode() with a different return type, or Equals() overloading Equals(object) - the existing InteropExplicitTypeTests covering those scenarios still pass

The same dedupe is applied to the explicit interface implementation path, where identical redeclared signatures from multiple interfaces could previously also be reported twice.

Testing

Added a regression test mirroring the discussion repro (interface implementation exposed through an object-typed property). Full Jint.Tests and Jint.Tests.PublicInterface suites pass on net10.0 and net472.

🤖 Generated with Claude Code

…tion

When resolving a member against a concrete type, candidate methods are
collected both from the type itself and from every implemented interface.
An implicitly implemented interface method was therefore added twice,
showing up as a duplicated candidate signature in detailed resolution
error messages (e.g. "candidate signatures: MyMethod(String a),
MyMethod(String a)") and doing redundant work during overload resolution.

Skip interface-sourced (and object-sourced) methods whose signature is
already covered by an earlier candidate. The signature comparison is
structural so generic methods match across their distinct generic
parameter instances, while genuinely different methods - such as an
interface method hiding an object method with a different return type -
are kept.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lahma
lahma enabled auto-merge (squash) July 20, 2026 17:55
@lahma
lahma merged commit d46d452 into sebastienros:main Jul 20, 2026
7 of 8 checks passed
@lahma
lahma deleted the method-signature-duplicated branch July 20, 2026 18:25
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