{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeApplications #-}

-- | Items in this module should /not/ be considered part of Crucible-LLVM's
-- API, they are exported only for the sake of the test suite.
module Lang.Crucible.LLVM.Internal
  ( assertionsEnabled
  ) where

import qualified Control.Exception as X
import           Data.Functor ((<&>))

-- | Check if assertions are enabled.
--
-- Note [Asserts]: When optimizations are enabled, GHC compiles 'X.assert' to
-- a no-op. However, Cabal enables @-O1@ by default. Therefore, if we want our
-- assertions to be checked by our test suite, we must carefully ensure that we
-- pass the correct flags to GHC for the @lib:crucible-llvm@ target. We verify
-- that we have done so by asserting as much in the test suite.
assertionsEnabled :: IO Bool
assertionsEnabled :: IO Bool
assertionsEnabled = do
  forall e a. Exception e => IO a -> IO (Either e a)
X.try @X.AssertionFailed (Bool -> IO () -> IO ()
forall a. (?callStack::CallStack) => Bool -> a -> a
X.assert Bool
False (() -> IO ()
forall a. a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ())) IO (Either AssertionFailed ())
-> (Either AssertionFailed () -> Bool) -> IO Bool
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&>
    \case
      Left AssertionFailed
_ -> Bool
True
      Right () -> Bool
False