purescript-lua
purescript-lua copied to clipboard
Stack overflow in Prelude generic tests
As the title says. I tried to get tests working for the Prelude, and I was mostly successful, with the caveat that the inclusion of the Generic tests causes a stack overflow in the definition of eqList. This seems more plausibly to be a bug with the backend's implementation of derive instance Generic than an issue with the Prelude itself.
Specifically,
data List a = Nil | Cons { head :: a, tail :: List a }
cons :: forall a. a -> List a -> List a
cons head tail = Cons { head, tail }
derive instance genericList :: G.Generic (List a) _
instance eqList :: Eq a => Eq (List a) where
eq x y = GEq.genericEq x y
results in the offending definitions
M.Test_Data_Generic_Rep_eqList = function(dictEq)
return {
eq = M.Data_Eq_Generic_genericEq
(M.Test_Data_Generic_Rep_genericList)
(M.Test_Data_Generic_Rep_genericEqSum(
M.Data_Eq_Generic_genericEqConstructor(
M.Data_Eq_Generic_genericEqArgument(
M.Test_Data_Generic_Rep_eqRec(
M.Data_Eq_eqRowCons(
M.Test_Data_Generic_Rep_eqRowCons
(M.Test_Data_Generic_Rep_tailIsSymbol)
(M.Test_Data_Generic_Rep_eqList(dictEq))
)
()
(M.Test_Data_Generic_Rep_headIsSymbol)
(dictEq)
)
)
)
)
)
}
end
M.Test_Data_Generic_Rep_eqList1 = M.Test_Data_Generic_Rep_eqList(M.Data_Eq_eqInt)
(indents added for clarity.)
Thank you for the report, I will look into it this week.
@UnrelatedString I couldn't reproduce the problem - list equality works, check this PR out.
Very strange... I repro'd on a CI runner fine just now. Looking at the Golden Test, it appears that it uses an eta-expanded definition eq x y = GEq.genericEq x y, where eq = GEq.genericEq might cause issues with eager circular references in a way known and accepted even for the JS backend... and I thought I remembered the test in the Prelude repo itself being the former, but it's defined precisely the same way.
...I only now realized that just because the error message in the generated Lua points to the definition doesn't mean the definition itself causes the error 😭😭😭 Turns out, it's specifically testing that cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil) which causes the stack overflow--the non-equality test case doesn't have this issue, and I was able to repro even more minimally with (Nil :: List Int) == Nil.
Incidentally, it seems that derived Functor instances may also be faulty? Trying to map over an Either errors trying to index a function.
...and a long enough do block stack overflows just by the scale of the nested bind calls ;_;