Skip to content

SRTP committed overload does not match expected overload #12064

@NinoFloris

Description

@NinoFloris

SRTP committed overload does not match expected overload

Minimized repro:

type CaseName =
    static member ToCaseName<'a, 'b when 'a : null>(value: 'a) = failwith "just here to force delayed resolution."

    [<CompilerMessage("CaseName.ToCaseName",0)>]
    static member ToCaseName(value: 'a) = 
        let case, _ = Reflection.FSharpValue.GetUnionFields(value, typeof<'a>) in case.Name 

    static member inline Invoke(value: 'a) : string =
        let inline call (other: ^M, value: ^I) = ((^I or ^M) : (static member ToCaseName: ^I -> string) value)
        call (Unchecked.defaultof<CaseName>, value)

type DU =
    | Case
    // When this method exists, we emit DU.ToCaseName as a warning, 
    // yet we execute the code belonging to CaseName.ToCaseName
    [<CompilerMessage("DU.ToCaseName",0)>]
    static member ToCaseName(x: DU) = 
        match x with 
        | Case -> "Customized"

[<EntryPoint>]
let main argv =
    System.Console.WriteLine(CaseName.Invoke(Case)) // writes "Case" but warns "DU.ToCaseName"
    0

Given the overload tiebreakers you would expect a double-barreled SRTP call to pick the concrete method over the generic one. It kind of seems like this is happening (the warning betrays that much) however when you run/inspect the emitted code it actually executes the generic method.

/cc: @dsyme @gusty

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Compiler-SRTPbugs in SRTP inference, resolution, witness passing, code genBugImpact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.

    Type

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions