diff --git a/changelog/2024-02-16T16_42_52+01_00_fix2593 b/changelog/2024-02-16T16_42_52+01_00_fix2593 new file mode 100644 index 0000000000..cf3b3167cf --- /dev/null +++ b/changelog/2024-02-16T16_42_52+01_00_fix2593 @@ -0,0 +1 @@ +FIXED: HDL generation fails when using multiple-hidden feature in combination with synthesis attributes [#2593](https://github.com/clash-lang/clash-compiler/issues/2593) diff --git a/clash-lib/src/Clash/Core/Type.hs b/clash-lib/src/Clash/Core/Type.hs index 87c9387e75..958c057b7f 100644 --- a/clash-lib/src/Clash/Core/Type.hs +++ b/clash-lib/src/Clash/Core/Type.hs @@ -2,7 +2,7 @@ Copyright : (C) 2012-2016, University of Twente, 2016 , Myrtle Software Ltd, 2017 , Google Inc. - 2021 , QBayLogic B.V. + 2021-2024, QBayLogic B.V. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. @@ -452,6 +452,10 @@ funSubst funSubst _ Nothing = const Nothing funSubst tcm (Just s) = uncurry go where + -- AnnType cannot be matched in type-families within regular GHC (as they + -- are type synonyms) so it is fine to skip over them here. + go (AnnType _ t1) t2 = go t1 t2 + go (VarTy nmF) ty = case lookup nmF s of Nothing -> Just ((nmF,ty):s) -- Given, for example, the type family definition: @@ -470,6 +474,10 @@ funSubst tcm (Just s) = uncurry go Just ty' | ty' `aeqType` ty -> Just s _ -> Nothing + -- Only look through annotations in RHS after the VarTy case, so we can + -- preserve annotations in the substitution created by the VarTy case above + go t1 (AnnType _ t2) = go t1 t2 + -- [Note] funSubst FunTy -- -- Whenever type classes have associated types whose instances 'map' to @@ -495,13 +503,11 @@ funSubst tcm (Just s) = uncurry go , argView tcm r2 -- See [Note: Eager type families] ) - go ty1@(ConstTy _) ty2 = - -- Looks through AnnType - if ty1 `aeqType` ty2 then Just s else Nothing + go (ConstTy c1) (ConstTy c2) + | c1 == c2 = Just s - go ty1@(LitTy _) ty2 = - -- Looks through AnnType - if ty1 `aeqType` ty2 then Just s else Nothing + go (LitTy l1) (LitTy l2) + | l1 == l2 = Just s go _ _ = Nothing diff --git a/tests/Main.hs b/tests/Main.hs index b56019fe9a..178c980464 100755 --- a/tests/Main.hs +++ b/tests/Main.hs @@ -788,6 +788,7 @@ runClashTest = defaultMain $ clashTestRoot , outputTest "T2510" def{hdlTargets=[VHDL], clashFlags=["-DNOINLINE=OPAQUE"]} #endif , outputTest "T2542" def{hdlTargets=[VHDL]} + , runTest "T2593" def{hdlSim=[]} ] <> if compiledWith == Cabal then -- This tests fails without environment files present, which are only diff --git a/tests/shouldwork/Issues/T2593.hs b/tests/shouldwork/Issues/T2593.hs new file mode 100644 index 0000000000..882647e478 --- /dev/null +++ b/tests/shouldwork/Issues/T2593.hs @@ -0,0 +1,14 @@ +module T2593 where + +import Clash.Prelude +import Clash.Annotations.SynthesisAttributes + +topEntity :: + Signal System Bit -> + Signal System Bit `Annotate` 'StringAttr "breaka" "me" +topEntity dIn = + exposeClockResetEnable (register 0) clk rst en dIn + where + clk = clockGen + rst = resetGen + en = enableGen