-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Internal error: Undefined or unsolved type variable with SRTP chains #5973
Comments
Labeling as a bug due to the internal error - whether or not this should actually compile is a separate question, but from a usability standpoint the internal error needs to be done away with so your entire editor won't go red. |
From compiler office hours: @dsyme says:
@realvictorprm says
@dsyme says
|
I debugged the compiler and found out:
|
Is this in the body of the inline expression, or the copy of the inline expression (after it's been inlined into a callsite)? |
I think I've got a different reproduction for this issue which is based on the code from #4924. type Either<'l,'r> = Left of 'l | Right of 'r
type Maybe<'a> = Either<unit,'a>
let inline addfst x y = (x, y)
module Either =
let rmap f : Either<'l,'a> -> Either<'l,'b> =
function Right x -> Right (f x) | Left e -> Left e
type Multifunctor() =
static member inline mapB (f : ^b -> ^b0, (a : ^a, b : ^b)) : ^a * ^b0 = (a, f b)
// If you comment the line below you'll get an internal error undefined or unsolved type variable
// Otherwise it compiles but you won't get compile errors although the type signature ofwhatInTheWorld is wrong
// static member inline mapB (f : ^b -> ^b0, x : Either< ^a,^b>) : Either< ^a,^b0> = Either.rmap f x
static member inline mapB (f : ^b -> ^b0, (a : ^a, b : ^b, c : ^c)) : ^a * ^b0 * ^c = (a, f b, c)
let inline mapB_< ^mf, ^f, ^a, ^b when (^mf or ^a) : (static member mapB : ^f * ^a -> ^b)> (f : ^f, x : ^a) : ^b =
((^mf or ^a) : (static member mapB : ^f * ^a -> ^b) (f, x))
type Multitraverse() =
static member inline traverseBB (f : ^b1 -> ^b2, x : ^a1 * ^c2 * ^d3) = fun a -> printfn "hi"; a
static member inline traverseBB (f : ^b -> ^b0, (a : ^a, b : ^b)) : ^b1
when (Multifunctor or ^b0) : (static member mapB : _ * ^b0 -> ^b1) =
mapB_<Multifunctor,_,_,_> (addfst a, (f b))
let inline traverseBB_< ^mf, ^a, ^b, ^c, ^d when (^mf or ^a) : (static member traverseBB : (^a -> ^b) * ^c -> ^d)> (f : ^a -> ^b, x : ^c) : ^d =
((^mf or ^a) : (static member traverseBB : (^a -> ^b) * ^c -> ^d) (f, x))
let inline traverseBB (f : ^a -> ^b) (x : ^c) : ^d
when (Multitraverse or ^c) : (static member traverseBB : (^a -> ^b) * ^c -> ^d) =
// The intent of requiring monad is just trying to be lawful
traverseBB_<Multitraverse,^a,^b,^c,^d> (f, x)
let private maybeZero : int -> Maybe<int> =
function
| 0 -> Right 0
| _ -> Left ()
// This type clearly does not match the implementation, and yet it type checks
// full signature is: int -> Maybe<int> -> list<string> * int -> Either<string,list<string>>
// This selects the function traverseBB : (f : ^b -> ^b0, (a : ^a, b : ^b)) : ^b1
// (f : int -> Maybe<int>, (a : list<string>, b : int)) : Either<string, list<string>>
// Inner selected function is: mapB : _ * ^b0 -> ^b1
// : (^x -> (list<string> * ^x)) * Maybe<int> -> Either<string, list<string>>
// Which would be: mapB (f : ^b/int -> ^b0/list<string> * int, x : Either< ^a/unit, ^b/int>) : Either< ^a/unit,^b0/list<string> * int>
let private whatInTheWorld : list<string>*int -> Either<unit,list<string> * float> =
traverseBB maybeZero |
I referenced this in #6805 to make sure we pin down known status for this in that branch |
While digging into #4924 I found an example with SRTP chains which produces an internal error.
Repro steps
Try compiling this in FSI:
Will produce an error like:
FS0073: Internal Error: Undefined or unsolved type variable: ^_?35727
for the last function
appliedFoo
.Expected behavior
No internal error.
Actual behavior
An internal error is thrown.
Known workarounds
None
Related information
F# 4.5
The text was updated successfully, but these errors were encountered: