dotnet / dotnet/fsharp

SRTP committed overload does not match expected overload

Open
#12,064 3 comments 0 reactions 0 assignees View on GitHub
Area-Compiler-SRTP Bug Impact-Low
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

SRTP committed overload does not match expected overload

Minimized repro:

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

[]
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, value)

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

[]
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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.