Skip to content

Fix broken comparison of the generic methods - #990

Merged
dtchepak merged 2 commits into
nsubstitute:mainfrom
zvirja:fix-828-distinguish-generic-overloads
Aug 10, 2026
Merged

Fix broken comparison of the generic methods#990
dtchepak merged 2 commits into
nsubstitute:mainfrom
zvirja:fix-828-distinguish-generic-overloads

Conversation

@zvirja

@zvirja zvirja commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #828

Currently we compare generic methods by names which is wrong in case we e.g. have shadowing via new. Do proper generic definition comparison, so that we preserve methods identity. Added tests to validate the scenarios.

zvirja and others added 2 commits August 9, 2026 17:33
Argument matchers for generic methods failed to tell apart two distinct
overloads that share a name but differ by their generic method definition
(e.g. a base interface method and a `new` reimplementation in a derived
interface with a narrower generic constraint).

CanCompareGenericMethods identified generic overloads by name only, so a
specification built for the base overload was considered comparable to a
call on the derived overload. Combined with the assignability check on the
closed generic arguments, a base-typed matcher (Arg.Any<IOutBase>) would
match a call to the derived overload closed over a subtype (IOutDerived),
producing false matches when verifying calls and resolving return values.

Compare the generic method definitions instead of the names. This still
allows a single method to match calls closed over different (assignable)
type arguments, while keeping genuinely distinct overloads apart.

Fixes nsubstitute#828

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a regression scenario alongside the nsubstitute#828 field report: overriding a
generic method (as opposed to 'new' hiding it) keeps a single method slot,
so the spec and the recorded call resolve to the same generic method
definition whether the substitute is used through the derived or the base
type. This ensures comparing generic method definitions does not tighten
matching too far for legitimate overrides.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@zvirja
zvirja requested a review from dtchepak August 9, 2026 19:14
@dtchepak
dtchepak merged commit a466b7a into nsubstitute:main Aug 10, 2026
4 checks passed
@dtchepak

Copy link
Copy Markdown
Member

@zvirja happy for me to release current main as 6.2.0?

Should i set up the nuget-push environment to require a reviewer prior to it running?

@zvirja
zvirja deleted the fix-828-distinguish-generic-overloads branch August 10, 2026 14:20
@zvirja

zvirja commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

I am creating 2 more PRs and we could go after that.

Should i set up the nuget-push environment to require a reviewer prior to it running?

I am not sure I follow what you mean and exactly it happens. But I would say - no, if one creates a tag, we assume one knows what they are doing, so it's okay :)

@dtchepak

dtchepak commented Aug 10, 2026

Copy link
Copy Markdown
Member

Something like this:

image

if one creates a tag, we assume one knows what they are doing, so it's okay

You seem to be forgetting I am still involved with this project and have access to create tags 😅 🤣

I take your point though; definitely less friction to just tie it to releases, I just tend to be (overly?) cautious with this stuff. 😄

@zvirja

zvirja commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Something like this:

Wow, I didn't even know you could review those things 😮 So many projects I work alone on, so nice to learn 😅

I take your point though; definitely less friction to just tie it to releases, I just tend to be (overly?) cautious with this stuff. 😄

I wouldn't be much worried. Worst case scenario - we can always unlist things and bump versions to fix. I had to fix the mess so many times in my life until now, so I wouldn't worry at all. But of course we shall be reasonable in our actions 😅

@zvirja

zvirja commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@dtchepak Let's proceed with merge once me merge params. We have a huge issue with generics support, especially after we got Arg.AnyType - it allows some significant violation scenarios. Especially if you start playing with covariance/contravariance. I wanted to quickly fix it, but apparently the journey is far more complicated. I may finalize it later, but it shall come either as a part of next 6.x, or we even releaes 7.x if there are required breaking changes in how generics are handled.

This was referenced Aug 11, 2026
This was referenced Aug 15, 2026
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.

Argument matchers fail if null passed in to an out parameter of a generic derived type

2 participants