Open miguel-negrao opened 5 days ago
This would fix it:
diff --git a/src/Data/Extensible/Bits.hs b/src/Data/Extensible/Bits.hs
index 51708a9..b44f07b 100644
--- a/src/Data/Extensible/Bits.hs
+++ b/src/Data/Extensible/Bits.hs
@@ -138,7 +138,7 @@ instance FromBits r a => FromBits r (Const a b) where
fromBits = Const . fromBits
toBits = toBits . getConst
-instance (Bits r, FromBits r (h (TargetOf x))) => FromBits r (Field h x) where
+instance (Bits r, KnownNat (BitWidth (h (TargetOf x))), FromBits r (h (TargetOf x))) => FromBits r (Field h x) where
type BitWidth (Field h x) = BitWidth (h (TargetOf x))
fromBits = Field . fromBits
toBits = toBits . getField
ChatGPT gives the following explanation to why GHC can no longer deduce KnownNat automatically:
The reason you're encountering this error in GHC 9.10.1, whereas it didn't appear in GHC 9.8 and earlier versions, is due to a change in how GHC handles superclass constraints in instance declarations starting from GHC 9.6 and onwards. This change affects the way GHC infers and requires superclass constraints in the context of instance declarations.
Background:
In earlier versions of GHC (before 9.6), the compiler would automatically expand superclass constraints of constraints present in the instance context. This means that if you had a constraint like FromBits r a
in your instance context, GHC would automatically consider its superclass constraints (like KnownNat (BitWidth a)
) when resolving instance declarations.
Change in GHC 9.6 and Later:
Starting from GHC 9.6, the compiler's behavior regarding superclass constraints became more conservative to improve type inference reliability and avoid potential issues like infinite loops in the type checker. Specifically, GHC no longer automatically expands superclass constraints of constraints in instance contexts during instance resolution.
Impact on Your Code:
In your code, the FromBits
class has a superclass constraint KnownNat (BitWidth a)
:
class (Bits r, KnownNat (BitWidth a)) => FromBits r a where
type BitWidth a :: Nat
fromBits :: r -> a
toBits :: a -> r
In your instance declaration for FromBits r (Field h x)
, you have:
instance (Bits r, FromBits r (h (TargetOf x))) => FromBits r (Field h x) where
type BitWidth (Field h x) = BitWidth (h (TargetOf x))
fromBits = Field . fromBits
toBits = toBits . getField
Under GHC 9.8 and earlier, GHC would automatically deduce KnownNat (BitWidth (h (TargetOf x)))
from the FromBits r (h (TargetOf x))
constraint because it would expand the superclass constraints of FromBits
. However, in GHC 9.10.1, this automatic expansion doesn't happen, so GHC cannot deduce the required KnownNat
constraint unless you specify it explicitly.
Why GHC Changed This Behavior:
What You Need to Do:
To fix the issue in GHC 9.10.1, you need to explicitly include the KnownNat
constraint in your instance declaration:
instance (Bits r, KnownNat (BitWidth (h (TargetOf x))), FromBits r (h (TargetOf x))) => FromBits r (Field h x) where
type BitWidth (Field h x) = BitWidth (h (TargetOf x))
fromBits = Field . fromBits
toBits = toBits . getField
By adding KnownNat (BitWidth (h (TargetOf x)))
to the context, you provide GHC with the necessary constraint that it cannot infer automatically in the newer version.
Summary:
KnownNat
.Additional Reference:
For more details on this change, you can refer to the GHC User's Guide section on Superclass constraints. It explains how GHC handles superclass constraints and the rationale behind requiring them to be explicit in certain contexts.
Conclusion:
The change in GHC's behavior regarding superclass constraints in instance declarations is the reason you're seeing this error in GHC 9.10.1. By adjusting your code to include the necessary constraints explicitly, you align with the new requirements and ensure your code remains compatible with future GHC versions.
Currently doesn't build with GHC 9.10.1