-
Notifications
You must be signed in to change notification settings - Fork 164
Open
Labels
Description
Motivating example:
data MsgConfig = MsgConfig
{ _msgChannelWidth :: Nat
, _msgDataLen :: Nat
}
type family MsgChannelWidth (cfg :: MsgConfig) :: Nat where
MsgChannelWidth ('MsgConfig x _) = x
type family MsgDataLen (cfg :: MsgConfig) :: Nat where
MsgDataLen ('MsgConfig _ x) = x
type KnownMsgConfig cfg = (KnownNat (MsgDataLen cfg), KnownNat (MsgChannelWidth cfg))
data Message (cfg :: MsgConfig) = Status
{ _msg_channel :: Unsigned (MsgChannelWidth cfg)
, _msg_data :: Vec (MsgDataLen cfg) (Unsigned 8)
, _msg_chksum :: Unsigned 4
}
deriving (Bundle, Generic)
deriving instance (KnownMsgConfig cfg) => NFDataX (Message cfg)
deriving instance (KnownMsgConfig cfg) => BitPack (Message cfg)
deriveAutoReg ''MessageWhich gives an error:
• Could not deduce ‘KnownNat (MsgChannelWidth cfg)’
arising from the superclasses of an instance declaration
from the context: KnownNat (MsgDataLen cfg)
bound by the instance declaration at src/Protocols.hs:97:1-23
• In the instance declaration for ‘AutoReg (Message cfg)’
|
97 | deriveAutoReg ''Message
And this is because deriveAutoReg, naively (?), assumes the NFDataX constraint on AutoReg can never introduce additional constraints beyond what AutoReg itself directly implies.
In this case NFDataX Requires both (KnownNat (MsgDataLen cfg), KnownNat (MsgChannelWidth cfg)) but AutoReg only needs KnownNat (MsgDataLen cfg) directly. So KnownNat (MsgChannelWidth cfg) is not added to the instance and the error is given.
This example can be re-written to work. But it's a footgun imo and I don't see/know a reason why it shouldn't also look through what constraints are required via superclasses.
See: https://clash-lang.discourse.group/t/deriveautoreg-with-superclass-constraints/100
Reactions are currently unavailable