-
Notifications
You must be signed in to change notification settings - Fork 826
Description
Today it's possible to express SRTP constraints that involve a concrete type like
type Foo =
static member inline Invoke< ^N, 'a, 'b when (Foo or ^N): (static member Bar: 'a -> 'b)> source = ...
Yet there's no way to then use this constraint in a trait call
type Foo =
static member inline Invoke< ^N, 'a, 'b when (Foo or ^N): (static member Bar: 'a -> 'b)> source =
((Foo or ^N): (static member Bar: _ -> _)(source)) // doesn't compile
Now I know it's advised not to use explicit signatures, especially for SRTP, though I'm unsure why the concrete type in the signature is allowed then.
I'd say it should be removed from signatures or get trait call syntax to match.
Though if you're willing to tolerate some compiler warnings it can be worked around like so
type Foo =
static member inline Invoke< ^N, 'a, 'b when (Foo or ^N): (static member Bar: 'a -> 'b)> source =
let inline call (_: ^M, a) =
((^M or ^N): (static member Bar: _ -> _)(a))
call (Unchecked.defaultof<Foo>, source)
The compiler seemingly unifies ^M
with Foo
and allows that trait call to piggyback on the outer function's constraint. Only surfacing a warning, not an error, that (^M or ^N): (static member Bar: 'a -> 'b)
is a missing constraint at the trait call location. This may or may not be a compiler bug ;)