Skip to content

Commit

Permalink
Fully resolve type synonyms when deriving bit representations.
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanG077 committed May 16, 2022
1 parent 3f7b965 commit 6964085
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
1 change: 1 addition & 0 deletions changelog/2022-05-16T10_15_05+02_00_bitrepr_resolve_types
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FIXED: Fully resolve type synonyms when deriving bit representations.
48 changes: 28 additions & 20 deletions clash-prelude/src/Clash/Annotations/BitRepresentation/Deriving.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,35 @@ import Clash.Annotations.BitRepresentation.Util
import qualified Clash.Annotations.BitRepresentation.Util
as Util

import Clash.Annotations.Primitive (hasBlackBox)
import Clash.Annotations.Primitive (hasBlackBox)
import Clash.Class.BitPack
(BitPack, BitSize, pack, packXWith, unpack)
import Clash.Class.Resize (resize)
import Language.Haskell.TH.Compat (mkTySynInstD)
import Clash.Sized.BitVector (BitVector, low, (++#))
import Clash.Class.Resize (resize)
import Language.Haskell.TH.Compat (mkTySynInstD)
import Clash.Sized.BitVector (BitVector, low, (++#))
import Clash.Sized.Internal.BitVector (undefined#)
import Control.DeepSeq (NFData)
import Control.Monad (forM)
import Control.Applicative (liftA3)
import Control.DeepSeq (NFData)
import Control.Monad (forM)
import Data.Bits
(shiftL, shiftR, complement, (.&.), (.|.), zeroBits, popCount, bit, testBit,
Bits, setBit)
import Data.Data (Data)
import Data.Containers.ListUtils (nubOrd)
import Data.Data (Data)
import Data.Containers.ListUtils (nubOrd)
import Data.List
(mapAccumL, zipWith4, sortOn, partition)
import Data.Typeable (Typeable)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import qualified Data.Set as Set
import Data.Proxy (Proxy(..))
import GHC.Exts (Int(I#))
import GHC.Generics (Generic)
import GHC.Integer.Logarithms (integerLog2#)
import GHC.TypeLits (natVal)
import Data.Typeable (Typeable)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import qualified Data.Set as Set
import Data.Proxy (Proxy(..))
import GHC.Exts (Int(I#))
import GHC.Generics (Generic)
import GHC.Integer.Logarithms (integerLog2#)
import GHC.TypeLits (natVal)
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Datatype (resolveTypeSynonyms)

-- | Used to track constructor bits in packed derivation
data BitMaskOrigin
Expand Down Expand Up @@ -452,8 +454,10 @@ deriveDataRepr constrDerivator fieldsDerivator typ = do
constrMasks
constrValues

resolvedType <- resolveTypeSynonyms typ

letE decls [| DataReprAnn
$(liftQ $ return typ)
$(liftQ $ return resolvedType)
($dataSizeExp + constrSize)
$(listE constrReprs) |]
_ ->
Expand Down Expand Up @@ -784,8 +788,11 @@ derivePackedAnnotation = deriveAnnotation packedDerivator
collectDataReprs :: Q [DataReprAnn]
collectDataReprs = do
thisMod <- thisModule
go [thisMod] Set.empty []
unresolved <- go [thisMod] Set.empty []
mapM resolveTyps unresolved
where
resolveTyps (DataReprAnn t s c)
= liftA3 DataReprAnn (resolveTypeSynonyms t) (pure s) (pure c)
go [] _visited acc = return acc
go (x:xs) visited acc
| x `Set.member` visited = go xs visited acc
Expand Down Expand Up @@ -986,8 +993,9 @@ deriveBitPack :: Q Type -> Q [Dec]
deriveBitPack typQ = do
anns <- collectDataReprs
typ <- typQ
rTyp <- resolveTypeSynonyms typ

ann <- case filter (\(DataReprAnn t _ _) -> t == typ) anns of
ann <- case filter (\(DataReprAnn t _ _) -> t == rTyp) anns of
[a] -> return a
[] -> fail "No custom bit annotation found."
_ -> fail "Overlapping bit annotations found."
Expand Down

0 comments on commit 6964085

Please sign in to comment.