-
Notifications
You must be signed in to change notification settings - Fork 832
Description
I will demonstrate a short piece of code, using SRTPs and overload resolution, where the compilation will either succeed or fail, depending on the runtime execution path.
Repro steps
let compiles = true
type A<'t> = A of 't
type B<'t> = B of 't
type Bind = Bind with
static member (>>=) (A t, f: 'T -> A<'U> ) = f t
static member (>>=) (B t, f: 'T -> B<'U> ) = f t
static member inline Invoke (source: 'MT) (binder: 'T -> 'MU) : 'MU =
let inline call (_mthd: 'M, input: 'I, _output: 'R, f) = ((^M or ^I or ^R) : (static member (>>=) : _*_ -> _) input, f)
call (Bind, source, Unchecked.defaultof<'MU>, binder)
type Result = Result with
static member Return (_: A<'a>) = A
static member Return (_: B<'a>) = B
static member inline Invoke (x: 'T) : 'MT =
let inline call (_mthd: ^M, output: ^R) = ((^M or ^R) : (static member Return : _ -> _) output)
call (Result, Unchecked.defaultof<'MT>) x
type T<'m> () = class end
type U<'m,'t> () = class end
let inline createT (_: 'mit) =
let _ = if compiles then Bind.Invoke (Result.Invoke Unchecked.defaultof<'t> : 'mt) ((fun _ -> Result.Invoke (U<'mt,'t>()))) else Unchecked.defaultof<'mit>
T() : T<'mt>
type T<'m> with static member inline Return (_) = fun (_:'t) -> U() |> Result.Invoke |> createT
// test
let (u: T<A<unit>>) = Result.Invoke () // works !!! Now try with compiles = false (???)
Expected behavior
Should compile or not (hopefully the former) regardless of the content of compiles.
Actual behavior
It compiles if compiles = true but when compiles = false it fails with error FS0073: internal error: Undefined or unsolved type variable: ^_?21440
Known workarounds
Use compile = true but it will execute unnecessarily some piece of code that is used only to drive type inference to create the desired constraints.
Related information
I've tested it in many environments and different versions of F#. Actually I'm seeing this since long time ago (4 years at least) but it's the first time I manage to create a minimal repro.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status