ghc-check-0.5.0.2: src/GHC/Check/Util.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE CPP, TemplateHaskell #-}
module GHC.Check.Util (MyVersion(..), liftTyped, gcatchSafe) where
import Control.Exception.Safe
import Control.Monad.IO.Class (MonadIO(liftIO))
import Data.Version ( Version, parseVersion )
import GHC (Ghc, gcatch)
import GHC.Exts (IsList (fromList), toList)
import Language.Haskell.TH ( TExpQ )
import Language.Haskell.TH.Syntax as TH
import qualified Text.Read as Read
-- | A wrapper around 'Version' with TH lifting
newtype MyVersion = MyVersion Version
deriving (Eq, IsList, Show)
instance Lift MyVersion where
#if MIN_VERSION_template_haskell(2,16,0)
liftTyped = liftMyVersion
#endif
lift = unTypeQ . liftMyVersion
instance Read MyVersion where
readPrec = Read.lift $ MyVersion <$> parseVersion
liftMyVersion :: MyVersion -> TExpQ MyVersion
liftMyVersion ver = do
verLifted <- TH.lift (toList ver)
[|| fromList $$(pure $ TExp verLifted) ||]
#if !MIN_VERSION_template_haskell(2,16,0)
liftTyped :: Lift a => a -> TExpQ a
liftTyped = unsafeTExpCoerce . lift
#endif
gcatchSafe :: forall e a . Exception e => Ghc a -> (e -> Ghc a) -> Ghc a
gcatchSafe act h = act `gcatch` rethrowAsyncExceptions
where
rethrowAsyncExceptions :: e -> Ghc a
rethrowAsyncExceptions e
| isAsyncException e = liftIO . throwIO $ e
| otherwise = h e