Skip to content

Stack overflow in Prelude generic tests #32

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

Open
UnrelatedString opened this issue Mar 26, 2025 · 5 comments
Open

Stack overflow in Prelude generic tests #32

UnrelatedString opened this issue Mar 26, 2025 · 5 comments
Assignees

Comments

@UnrelatedString
Copy link
Contributor

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.)

@Unisay
Copy link
Owner

Unisay commented Mar 26, 2025

Thank you for the report, I will look into it this week.

@Unisay Unisay self-assigned this Mar 30, 2025
@Unisay
Copy link
Owner

Unisay commented Mar 30, 2025

@UnrelatedString I couldn't reproduce the problem - list equality works, check this PR out.

@UnrelatedString
Copy link
Contributor Author

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.

@UnrelatedString
Copy link
Contributor Author

Incidentally, it seems that derived Functor instances may also be faulty? Trying to map over an Either errors trying to index a function.

@UnrelatedString
Copy link
Contributor Author

...and a long enough do block stack overflows just by the scale of the nested bind calls ;_;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants