Skip to content

SRTP doesn't handle calling member hiding inherited members #5531

Description

@vbfox

When SRTP is used to call a member that is hiding an inherited member (C# new modifier) it fail to compile with the following error:

A unique overload for method 'Foo' could not be determined based on type information prior to this program point.
A type annotation may be needed. Candidates:

abstract member Base.Foo : unit -> unit,
member Derived.Foo : unit -> unit

Repro steps

The last line of this program should compile as the type is fully known and the correct Foo method can be chosen (The compiler does it correctly when the method is called directly without SRTP)

type Base() =
    abstract member Foo : unit -> unit
    default this.Foo() = printfn "Base"
    
type Derived() =
    inherit Base()
    member this.Foo() = printfn "Derived"
    
let inline callFoo< ^T when ^T : (member Foo: unit -> unit) > (t: ^T) =
    (^T : (member Foo: unit -> unit) (t))
    
let b = Base()
let d = Derived()
let bd = d :> Base

b.Foo()
bd.Foo()
d.Foo()

callFoo<Base> b
callFoo<Base> bd
callFoo<Base> d
// A unique overload for method 'Foo' could not be determined based on type information prior to this program point.
// A type annotation may be needed. Candidates:
//   abstract member Base.Foo : unit -> unit,
//   member Derived.Foo : unit -> unit
callFoo<Derived> d

Known workarounds

None AFAIK, if a library you use suddenly does it (Like Roslyn just did between 2.8.2 and 2.9.0) you must rewrite everything without SRTP.

Related information

Tested on SDK 2.1.300 & 2.1.400

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions