Skip to content

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

@vbfox

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

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