Skip to content

Fix overload resolution of static member extension#19698

Open
evgTSV wants to merge 6 commits into
dotnet:mainfrom
evgTSV:fix-static-meth-resolving
Open

Fix overload resolution of static member extension#19698
evgTSV wants to merge 6 commits into
dotnet:mainfrom
evgTSV:fix-static-meth-resolving

Conversation

@evgTSV
Copy link
Copy Markdown
Contributor

@evgTSV evgTSV commented May 6, 2026

Description

The compiler resolution logic failed to locate static extension members when using the Type<args>.Member syntax. This construction is treated as a "resolve dot" operation within an expression. Previously, the lookup was restricted by the LookupIsInstance.Yes filter.

The core issue lies in the inconsistent behavior of LookupIsInstance.Yes: it allows static intrinsic members to pass through while filtering out static extension members. This inconsistency led to incomplete candidate sets during resolution. My solution replaces LookupIsInstance.Yes with LookupIsInstance.Ambivalent to ensure both intrinsic and extension static members are correctly identified and considered.

​​(Note: ResolveExprDotLongIdent is not used exclusively for resolving instance members, making Ambivalent the correct choice for this context).​​

Fixes #19664

Checklist

  • Test cases added
  • Release notes entry updated:

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

❗ Release notes required


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/11.0.100.md

Copy link
Copy Markdown
Member

@T-Gro T-Gro left a comment

Choose a reason for hiding this comment

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

Review Summary

Verdict: Approve — the fix is correct and well-targeted.

Root Cause Analysis

The bug occurs because ResolveExprDotLongIdent (line 4182) initiates member lookup with LookupIsInstance.Yes for dot-access on expressions. When you write StaticGeneric<int>.Bar(42), the <int> type application makes this an expression dot-access rather than a simple identifier chain. The intrinsic static Bar() is found (since MethodItem doesn't pre-filter by instance/static), but ExtensionMethInfosOfTypeInScope applies the Yes filter and excludes the static extension Bar(_: int). For non-generic types like StaticNonGeneric.Bar(42), the path goes through ResolveExprLongIdentPrim with LookupIsInstance.No, so static extensions are found correctly.

The fix correctly detects the mismatch between the instance filter and the actual intrinsic methods, widening to Ambivalent so extension method search includes all candidates. Overload resolution then picks the right overload downstream.

Nits

  1. .fsproj indentation — line 67 uses a tab character while the rest of the file uses 4 spaces.
  2. Missing trailing newline in StaticMethodResolution.fs.

Suggestion (non-blocking)

The PropertyItem branch (~line 2858-2868) has a similar ExtensionMethInfosOfTypeInScope call with isInstanceFilter. The same bug could manifest when a generic type has a static property and a same-named static extension method. Consider applying the same widening logic there (or filing a follow-up issue).

<Compile Include="Conformance\BasicGrammarElements\MemberDefinitions\OptionalDefaultParamArgs\OptionalDefaultParamArgs.fs" />
<Compile Include="Conformance\BasicGrammarElements\MemberDefinitions\OverloadingMembers\OverloadingMembers.fs" />
<Compile Include="Conformance\BasicGrammarElements\MethodResolution\MethodResolution.fs" />
<Compile Include="Conformance\BasicGrammarElements\MethodResolution\StaticMethodResolution.fs" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: This line uses a tab character while the rest of the file uses 4 spaces.

"""
|> withOptions ["--nowarn:1125"]
|> typecheck
|> shouldSucceed No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Missing trailing newline at end of file.

@T-Gro T-Gro self-requested a review May 12, 2026 07:30
@T-Gro T-Gro added the AI-reviewed PR reviewed by AI review council label May 12, 2026
@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-reviewed PR reviewed by AI review council

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Overload resolution of static member extensions for generic types broken

2 participants