acid-state / safecopy

An extension to Data.Serialize with built-in version control
60 stars 37 forks source link

deriveSafeCopy not working for mutual recursive data-types in GHC 9.2.4 #90

Open marco-comini opened 2 years ago

marco-comini commented 2 years ago

Hi folks, I've just installed GHC 9.2.4 (now that is the recommended versio) and tried to compile one of my projects that is working fine in GHC 8.10.7.

To rule out many details, let's say that I have to define two mutual recursive types TypeA and Type B. With 9.2.4 I get errors that can be abstracted as

Could not deduce (SafeCopy TypeB) ... arising from a use of ‘getSafePut’ ... in $(deriveSafeCopy 0 'base ''TypeA)

and if I try to swap the order of definitions of TypeA/TypeB I get the dual error message. Am I missing something new that has to be done with 9.2.4 or is it a bug in deriveSafeCopy?

Thanks in advance for any help.

ddssff commented 2 years ago

Can you provide a self contained example of the failure?

marco-comini commented 2 years ago

{-# LANGUAGE TemplateHaskell #-} import qualified Data.SafeCopy as SC

data A = A B | C data B = B A

$(SC.deriveSafeCopy 0 'SC.base ''A) $(SC.deriveSafeCopy 0 'SC.base ''B)

(that also swapping the last two lines gives error)

stepcut commented 2 years ago

I ran into the same issue a while ago. I did not keep great notes, but it seemed to me like it was a new restriction in TH. I may or may not have found a relevant bug in the GHC bug tracker. My work-around was to use Generics instead,

#if __GLASGOW_HASKELL >= __900__
instance SafeCopy NavBar where version = 1
instance SafeCopy NavBarItem where version = 1
#else
$(deriveSafeCopy 1 'base ''NavBar)
$(deriveSafeCopy 1 'base ''NavBarItem)
#endif

So, my inclination is to blame GHC 9.2, but it would be nice if someone could figure out what is really happening and if the deriveSafeCopy can be tweaked to handle this situation with GHC 9.2. In the meantime, the Generics work-around seems reasonable. In fact, some might argue that Generics should be preferred over TH anyway. But, I have no idea how they compare performance-wise.