Skip to content

Commit 2714056

Browse files
committed
Add BitPack instance for Index 0
1 parent 1d49cd2 commit 2714056

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

cabal.project

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,8 @@ package regex-tdfa
8787

8888
-- rewrite-inspector-0.1.0.11 uses brick-0.50 which doesn't compile with vty-6.0
8989
constraints: vty < 6.0
90+
91+
source-repository-package
92+
type: git
93+
location: https://github.com/clash-lang/ghc-typelits-extra.git
94+
tag: 6de31070c86ad451abe329940ba4a0a4b571fb58

clash-prelude/src/Clash/Sized/Internal/Index.hs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import Prelude hiding (even, odd)
7575

7676
import Control.DeepSeq (NFData (..))
7777
import Data.Bits (Bits (..), FiniteBits (..))
78+
import Data.Constraint (Dict(..))
7879
import Data.Data (Data)
7980
import Data.Default.Class (Default (..))
8081
import Text.Read (Read (..), ReadPrec)
@@ -96,7 +97,7 @@ import GHC.Natural (naturalToInteger)
9697
import GHC.Stack (HasCallStack)
9798
import GHC.TypeLits (KnownNat, Nat, type (+), type (-),
9899
type (*), type (<=), natVal)
99-
import GHC.TypeLits.Extra (CLog)
100+
import GHC.TypeLits.Extra (CLog, CLogWZ)
100101
import Test.QuickCheck.Arbitrary (Arbitrary (..), CoArbitrary (..),
101102
arbitraryBoundedIntegral,
102103
coarbitraryIntegral, shrinkIntegral)
@@ -111,9 +112,10 @@ import Clash.Class.BitPack.BitIndex (replaceBit)
111112
import Clash.Sized.Internal (formatRange)
112113
import {-# SOURCE #-} Clash.Sized.Internal.BitVector (BitVector (BV), high, low, undefError)
113114
import qualified Clash.Sized.Internal.BitVector as BV
114-
import Clash.Promoted.Nat (SNat(..), snatToNum, natToInteger, leToPlusKN)
115+
import Clash.Promoted.Nat (SNat(..), SNatLE(..), snatToNum, natToInteger, leToPlusKN, compareSNat)
115116
import Clash.XException
116117
(ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX, seqX)
118+
import Unsafe.Coerce (unsafeCoerce)
117119

118120
{- $setup
119121
>>> import Clash.Sized.Internal.Index
@@ -184,10 +186,18 @@ instance NFData (Index n) where
184186
-- NOINLINE is needed so that Clash doesn't trip on the "Index ~# Integer"
185187
-- coercion
186188

187-
instance (KnownNat n, 1 <= n) => BitPack (Index n) where
188-
type BitSize (Index n) = CLog 2 n
189-
pack = packXWith pack#
190-
unpack = unpack#
189+
instance KnownNat n => BitPack (Index n) where
190+
type BitSize (Index n) = CLogWZ 2 n 0
191+
pack = case compareSNat (SNat @1) (SNat @n) of
192+
SNatGT -> const 0
193+
SNatLE | Dict <- fact @n @0 -> packXWith pack#
194+
unpack = case compareSNat (SNat @1) (SNat @n) of
195+
SNatGT -> const $ errorX
196+
"any value of type 'Index 0' is undefined"
197+
SNatLE | Dict <- fact @n @0 -> unpack#
198+
199+
fact :: forall n x. 1 <= n => Dict (CLogWZ 2 n x ~ CLog 2 n)
200+
fact = unsafeCoerce (Dict :: Dict (0~0))
191201

192202
-- | Safely convert an `SNat` value to an `Index`
193203
fromSNat :: (KnownNat m, n + 1 <= m) => SNat n -> Index m

0 commit comments

Comments
 (0)