Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
* Fix signature generation: type params with special characters missing backtick escaping. ([Issue #19595](https://github.com/dotnet/fsharp/issues/19595), [PR #19609](https://github.com/dotnet/fsharp/pull/19609))
* Fix internal error when using custom attribute with `[<Optional>]` value type parameter and no `[<DefaultParameterValue>]`. ([Issue #8353](https://github.com/dotnet/fsharp/issues/8353), [PR #19484](https://github.com/dotnet/fsharp/pull/19484))
* Fix parallel compilation of scripts ([PR #19649](https://github.com/dotnet/fsharp/pull/19649))
* Fix overload resolution of static member extension on generic types when the call uses explicit type arguments and an intrinsic overload of the same name exists. ([Issue #19664](https://github.com/dotnet/fsharp/issues/19664))

### Added

Expand Down
17 changes: 17 additions & 0 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2874,6 +2874,23 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf
| Some(MethodItem msets) when isLookUpExpr ->
let minfos = msets |> ExcludeHiddenOfMethInfos g ncenv.amap m

// If the intrinsic candidate set already disagrees with the strict
// instance/static filter (e.g. expression-form `Type<TArg>.Member` is
// resolved as a dot-expression with LookupIsInstance.Yes but yields
// static intrinsic members), relax the filter for the extension lookup
// so static extension members are also considered. See issue #19664.
let isAmbivalent =
minfos
|> List.exists (fun minfo ->
match isInstanceFilter with
| LookupIsInstance.Yes -> not minfo.IsInstance
| LookupIsInstance.No -> minfo.IsInstance
| LookupIsInstance.Ambivalent -> true)

let isInstanceFilter =
if isAmbivalent then LookupIsInstance.Ambivalent
else isInstanceFilter

// fold the available extension members into the overload resolution
let extensionMethInfos = ExtensionMethInfosOfTypeInScope ResultCollectionSettings.AllResults ncenv.InfoReader nenv ad optFilter isInstanceFilter m ty

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace Conformance.BasicGrammarElements

open FSharp.Test.Compiler
open Xunit

module StaticMethodResolution =

// Regression test for https://github.com/dotnet/fsharp/issues/19664
//
// When a static extension method is defined in a *different* [<AutoOpen>] module than
// the generic type it extends, and shares its name with an intrinsic static member,
// resolving the call via the explicit-type-argument syntax `Type<TArg>.Member(...)`
// previously failed with FS0505. The non-generic dotted form `Type.Member(...)`
// resolved correctly, so any regression test that omits the explicit type arguments
// does not actually exercise the bug. See the discussion at
// https://github.com/dotnet/fsharp/issues/19675#issuecomment-4373059900.
[<Fact>]
let ``Static extension on generic type resolves with explicit type arguments (issue 19664)`` () =
Fsx """
module Extensions =

type StaticGeneric<'T> =
static member Bar() = ()
static member Bar(_: int, _: int) = ()

[<AutoOpen>]
module StaticGenericExtensions =
type StaticGeneric<'T> with
static member Bar(_: int) = ()

module Program =
open Extensions

StaticGeneric<int>.Bar() // intrinsic, 0 args
StaticGeneric<int>.Bar(42) // regressed: extension, 1 arg, see issue 19664 (FS0505)
StaticGeneric<int>.Bar(42, 0) // intrinsic, 2 args
"""
|> withOptions ["--nowarn:1125"]
|> typecheck
|> shouldSucceed
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<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" />
<Compile Include="Conformance\BasicGrammarElements\ModuleAbbreviations\ModuleAbbreviations.fs" />
<Compile Include="Conformance\BasicGrammarElements\ModuleDefinitions\ModuleDefinitions.fs" />
<Compile Include="Conformance\BasicGrammarElements\NamespaceDeclGroups\NamespaceDeclGroups.fs" />
Expand Down
Loading