Overload resolution cannot choose between 'a->'b and Func<'a,'b> even though Func overload is incompatible
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
If there are two methods or constructors that differ by a parameter being an F# function or a `System.Func` of the equivalent type, the overload resolution fails.
If only the `System.Func` method exists, the code doesn't compile - so the ambiguity was wrong.
#### Repro steps
```f#
let conv (a : int) : float = float a
type X private (a : int, b : float) =
new (a : int, makeB : System.Func) = X(a, makeB.Invoke a) // Removing this line makes it compile
new (a : int, makeB : int -> float) = X(a, a |> makeB) // Removing this line instead shows the Func overload wouldn't have worked anyway
X(7, conv) |> ignore // A unique overload for method 'X' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : a:int * makeB:(int -> float) -> X, new : a:int * makeB:System.Func -> X
X(7, conv : int -> float) |> ignore // Doesn't help
// The same is true with method overloads
type Y =
static member A(a : int, makeB : System.Func) = ()
static member A(a : int, makeB : int -> float) = ()
Y.A(7, conv) |> ignore
Y.A(7, (conv : (int -> float)))
(Y.A : int * (int -> float) -> unit)(7, conv) |> ignore
```
#### Expected behavior
Since the `Func<…>` overload doesn't match, the `int->float` method is chosen
#### Actual behavior
The compiler cannot decide between overloads
#### Known workarounds
None known to me, type annotations don't seem to help
#### Related information
Some overlap with https://github.com/Microsoft/visualfsharp/issues/3563
* Windows
* Branch
* .NET 4.72 or Core 2.1
* Visual F# Tools 10.2 for F# 4.5 15.8.0.0. Commit Hash: 6e26c5bacc8c4201e962f5bdde0a177f82f88691.
Contributor guide
Assessment
This issue has not been assessed yet.