Skip to content

Overload resolution of static member extensions for generic types broken #19664

@hyazinthh

Description

@hyazinthh

I've run into a weird issue with static member extensions of generic types. When an extension is not defined in the same module as the type and has the same name as a type member, the extension cannot be found.

It works in any of the following cases:

  • Extension is defined in the same module as the type
  • Extended type does not have a member with the same name as the extension
  • Extended type is not generic
  • Extension is an instance extension

Repro steps

SharpLab Example

namespace Hello

module Extensions =

    // Static extensions for generic type in different module broken
    type StaticGeneric<'T> =
        static member Bar() = ()

    [<AutoOpen>]
    module StaticGenericExtensions =
        type StaticGeneric<'T> with
            static member Bar(_: int) = () // Broken
            static member Bar2(_: int) = () // Works if it has a different name

    // Works when in the same module
    type StaticGeneric<'T> with
        static member Bar(_: int, _: int) = ()

    // Works if non-generic type
    type StaticNonGeneric =
        static member Bar() = ()

    [<AutoOpen>]
    module StaticNonGenericExtensions =
        type StaticNonGeneric with
            static member Bar(_: int) = ()

    // Works if instance extension
    type InstanceGeneric<'T>() =
        member _.Bar() = ()

    [<AutoOpen>]
    module InstanceGenericExtensions =
        type InstanceGeneric<'T> with
            member _.Bar(_: int) = ()

module Program =
    open Extensions

    [<EntryPoint>]
    let main _ =
        StaticGeneric<int>.Bar()
        StaticGeneric<int>.Bar(42) // Error FS0505 : The member or object constructor 'Bar' does not take 1 argument(s). An overload was found taking 0 arguments.
        StaticGeneric<int>.Bar2(42)
        StaticGeneric<int>.Bar(42, 0)

        StaticNonGeneric.Bar()
        StaticNonGeneric.Bar(42)

        let foo = InstanceGeneric<int>()
        foo.Bar()
        foo.Bar 42

        0

Expected behavior

Should compile.

Actual behavior

Fails to compile with

Error FS0505 : The member or object constructor 'Bar' does not take 1 argument(s). An overload was found taking 0 arguments.

Known workarounds

  • Move extension to same module as type
  • Rename extension

Related information

Observed with .NET SDK 8.0.420 and .NET SDK 10.0.203

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions