Fix overload resolution of static member extension#19698
Conversation
…trisic methods exist
❗ Release notes required
|
T-Gro
left a comment
There was a problem hiding this comment.
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
.fsprojindentation — line 67 uses a tab character while the rest of the file uses 4 spaces.- 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" /> |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Nit: Missing trailing newline at end of file.
Description
The compiler resolution logic failed to locate static extension members when using the
Type<args>.Membersyntax. This construction is treated as a "resolve dot" operation within an expression. Previously, the lookup was restricted by theLookupIsInstance.Yesfilter.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 replacesLookupIsInstance.YeswithLookupIsInstance.Ambivalentto 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