    {-# LANGUAGE CPP, DeriveFunctor, DerivingVia, RankNTypes #-}
    {-# OPTIONS_GHC -funbox-strict-fields #-}
    -- -----------------------------------------------------------------------------
    --
    -- (c) The University of Glasgow, 2010
    --
    -- The Session type and related functionality
    --
    -- -----------------------------------------------------------------------------

    module GHC.Driver.Monad (
            -- * 'Ghc' monad stuff
            GhcMonad(..),
            Ghc(..),
            GhcT(..), liftGhcT,
            reflectGhc, reifyGhc,
            getSessionDynFlags,
            liftIO,
            Session(..), withSession, modifySession, modifySessionM,
            withTempSession,

            -- * Logger
            modifyLogger,
            pushLogHookM,
            popLogHookM,
            putLogMsgM,
            putMsgM,
            withTimingM,

            -- ** Warnings
            logWarnings, printException,
            WarnErrLogger, defaultWarnErrLogger
      ) where

    import GHC.Prelude

    import GHC.Driver.Session
    import GHC.Driver.Env
    import GHC.Driver.Errors ( printOrThrowWarnings, printBagOfErrors )

    import GHC.Utils.Monad
    import GHC.Utils.Exception
    import GHC.Utils.Error
    import GHC.Utils.Logger

    import GHC.Types.SrcLoc
    import GHC.Types.SourceError

    import Control.Monad
    import Control.Monad.Catch as MC
    import Control.Monad.Trans.Reader
    import Data.IORef

    -- -----------------------------------------------------------------------------
    -- | A monad that has all the features needed by GHC API calls.
    --
    -- In short, a GHC monad
    --
    --   - allows embedding of IO actions,
    --
    --   - can log warnings,
    --
    --   - allows handling of (extensible) exceptions, and
    --
    --   - maintains a current session.
    --
    -- If you do not use 'Ghc' or 'GhcT', make sure to call 'GHC.initGhcMonad'
    -- before any call to the GHC API functions can occur.
    --
    class (Functor m, ExceptionMonad m, HasDynFlags m, HasLogger m ) => GhcMonad m where
      getSession :: m HscEnv
      setSession :: HscEnv -> m ()

    -- | Call the argument with the current session.
    withSession :: GhcMonad m => (HscEnv -> m a) -> m a
    withSession :: forall (m :: * -> *) a. GhcMonad m => (HscEnv -> m a) -> m a
    withSession HscEnv -> m a
    f = forall (m :: * -> *). GhcMonad m => m HscEnv
    getSession forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= HscEnv -> m a
    f

    -- | Grabs the DynFlags from the Session
    getSessionDynFlags :: GhcMonad m => m DynFlags
    getSessionDynFlags :: forall (m :: * -> *). GhcMonad m => m DynFlags
    getSessionDynFlags = forall (m :: * -> *) a. GhcMonad m => (HscEnv -> m a) -> m a
    withSession (forall (m :: * -> *) a. Monad m => a -> m a
    return forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HscEnv -> DynFlags
    hsc_dflags)

    -- | Set the current session to the result of applying the current session to
    -- the argument.
    modifySession :: GhcMonad m => (HscEnv -> HscEnv) -> m ()
    modifySession :: forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
    modifySession HscEnv -> HscEnv
    f = do HscEnv
    h <- forall (m :: * -> *). GhcMonad m => m HscEnv
    getSession
                         forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
    setSession forall a b. (a -> b) -> a -> b
    $! HscEnv -> HscEnv
    f HscEnv
    h

    -- | Set the current session to the result of applying the current session to
    -- the argument.
    modifySessionM :: GhcMonad m => (HscEnv -> m HscEnv) -> m ()
    modifySessionM :: forall (m :: * -> *). GhcMonad m => (HscEnv -> m HscEnv) -> m ()
    modifySessionM HscEnv -> m HscEnv
    f = do HscEnv
    h <- forall (m :: * -> *). GhcMonad m => m HscEnv
    getSession
                          HscEnv
    h' <- HscEnv -> m HscEnv
    f HscEnv
    h
                          forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
    setSession forall a b. (a -> b) -> a -> b
    $! HscEnv
    h'

    withSavedSession :: GhcMonad m => m a -> m a
    withSavedSession :: forall (m :: * -> *) a. GhcMonad m => m a -> m a
    withSavedSession m a
    m = do
      HscEnv
    saved_session <- forall (m :: * -> *). GhcMonad m => m HscEnv
    getSession
      m a
    m forall (m :: * -> *) a b. MonadMask m => m a -> m b -> m a
    `MC.finally` forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
    setSession HscEnv
    saved_session

    -- | Call an action with a temporarily modified Session.
    withTempSession :: GhcMonad m => (HscEnv -> HscEnv) -> m a -> m a
    withTempSession :: forall (m :: * -> *) a.
    GhcMonad m =>
    (HscEnv -> HscEnv) -> m a -> m a
    withTempSession HscEnv -> HscEnv
    f m a
    m =
      forall (m :: * -> *) a. GhcMonad m => m a -> m a
    withSavedSession forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
    modifySession HscEnv -> HscEnv
    f forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> m a
    m

    ----------------------------------------
    -- Logging
    ----------------------------------------

    -- | Modify the logger
    modifyLogger :: GhcMonad m => (Logger -> Logger) -> m ()
    modifyLogger :: forall (m :: * -> *). GhcMonad m => (Logger -> Logger) -> m ()
    modifyLogger Logger -> Logger
    f = forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
    modifySession forall a b. (a -> b) -> a -> b
    $ \HscEnv
    hsc_env ->
        HscEnv
    hsc_env { hsc_logger :: Logger
    hsc_logger = Logger -> Logger
    f (HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env) }

    -- | Push a log hook on the stack
    pushLogHookM :: GhcMonad m => (LogAction -> LogAction) -> m ()
    pushLogHookM :: forall (m :: * -> *).
    GhcMonad m =>
    (LogAction -> LogAction) -> m ()
    pushLogHookM = forall (m :: * -> *). GhcMonad m => (Logger -> Logger) -> m ()
    modifyLogger forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (LogAction -> LogAction) -> Logger -> Logger
    pushLogHook

    -- | Pop a log hook from the stack
    popLogHookM :: GhcMonad m => m ()
    popLogHookM :: forall (m :: * -> *). GhcMonad m => m ()
    popLogHookM  = forall (m :: * -> *). GhcMonad m => (Logger -> Logger) -> m ()
    modifyLogger Logger -> Logger
    popLogHook

    -- | Put a log message
    putMsgM :: GhcMonad m => SDoc -> m ()
    putMsgM :: forall (m :: * -> *). GhcMonad m => SDoc -> m ()
    putMsgM SDoc
    doc = do
        DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
        Logger
    logger <- forall (m :: * -> *). HasLogger m => m Logger
    getLogger
        forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ Logger -> DynFlags -> SDoc -> IO ()
    putMsg Logger
    logger DynFlags
    dflags SDoc
    doc

    -- | Put a log message
    putLogMsgM :: GhcMonad m => WarnReason -> Severity -> SrcSpan -> SDoc -> m ()
    putLogMsgM :: forall (m :: * -> *).
    GhcMonad m =>
    WarnReason -> Severity -> SrcSpan -> SDoc -> m ()
    putLogMsgM WarnReason
    reason Severity
    sev SrcSpan
    loc SDoc
    doc = do
        DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
        Logger
    logger <- forall (m :: * -> *). HasLogger m => m Logger
    getLogger
        forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ Logger -> LogAction
    putLogMsg Logger
    logger DynFlags
    dflags WarnReason
    reason Severity
    sev SrcSpan
    loc SDoc
    doc

    -- | Time an action
    withTimingM :: GhcMonad m => SDoc -> (b -> ()) -> m b -> m b
    withTimingM :: forall (m :: * -> *) b.
    GhcMonad m =>
    SDoc -> (b -> ()) -> m b -> m b
    withTimingM SDoc
    doc b -> ()
    force m b
    action = do
        Logger
    logger <- forall (m :: * -> *). HasLogger m => m Logger
    getLogger
        DynFlags
    dflags <- forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
        forall (m :: * -> *) a.
    MonadIO m =>
    Logger -> DynFlags -> SDoc -> (a -> ()) -> m a -> m a
    withTiming Logger
    logger DynFlags
    dflags SDoc
    doc b -> ()
    force m b
    action

    -- -----------------------------------------------------------------------------
    -- | A monad that allows logging of warnings.

    logWarnings :: GhcMonad m => WarningMessages -> m ()
    logWarnings :: forall (m :: * -> *). GhcMonad m => WarningMessages -> m ()
    logWarnings WarningMessages
    warns = do
      DynFlags
    dflags <- forall (m :: * -> *). GhcMonad m => m DynFlags
    getSessionDynFlags
      Logger
    logger <- forall (m :: * -> *). HasLogger m => m Logger
    getLogger
      forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ Logger -> DynFlags -> WarningMessages -> IO ()
    printOrThrowWarnings Logger
    logger DynFlags
    dflags WarningMessages
    warns

    -- -----------------------------------------------------------------------------
    -- | A minimal implementation of a 'GhcMonad'.  If you need a custom monad,
    -- e.g., to maintain additional state consider wrapping this monad or using
    -- 'GhcT'.
    newtype Ghc a = Ghc { forall a. Ghc a -> Session -> IO a
    unGhc :: Session -> IO a }
      deriving (forall a b. a -> Ghc b -> Ghc a
    forall a b. (a -> b) -> Ghc a -> Ghc b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    <$ :: forall a b. a -> Ghc b -> Ghc a
    $c<$ :: forall a b. a -> Ghc b -> Ghc a
    fmap :: forall a b. (a -> b) -> Ghc a -> Ghc b
    $cfmap :: forall a b. (a -> b) -> Ghc a -> Ghc b
    Functor)
      deriving (Monad Ghc
    forall e a. Exception e => e -> Ghc a
    forall (m :: * -> *).
    Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
    throwM :: forall e a. Exception e => e -> Ghc a
    $cthrowM :: forall e a. Exception e => e -> Ghc a
    MonadThrow, MonadThrow Ghc
    forall e a. Exception e => Ghc a -> (e -> Ghc a) -> Ghc a
    forall (m :: * -> *).
    MonadThrow m
    -> (forall e a. Exception e => m a -> (e -> m a) -> m a)
    -> MonadCatch m
    catch :: forall e a. Exception e => Ghc a -> (e -> Ghc a) -> Ghc a
    $ccatch :: forall e a. Exception e => Ghc a -> (e -> Ghc a) -> Ghc a
    MonadCatch, MonadCatch Ghc
    forall b. ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b
    forall a b c.
    Ghc a -> (a -> ExitCase b -> Ghc c) -> (a -> Ghc b) -> Ghc (b, c)
    forall (m :: * -> *).
    MonadCatch m
    -> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
    -> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
    -> (forall a b c.
        m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
    -> MonadMask m
    generalBracket :: forall a b c.
    Ghc a -> (a -> ExitCase b -> Ghc c) -> (a -> Ghc b) -> Ghc (b, c)
    $cgeneralBracket :: forall a b c.
    Ghc a -> (a -> ExitCase b -> Ghc c) -> (a -> Ghc b) -> Ghc (b, c)
    uninterruptibleMask :: forall b. ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b
    $cuninterruptibleMask :: forall b. ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b
    mask :: forall b. ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b
    $cmask :: forall b. ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b
    MonadMask) via (ReaderT Session IO)

    -- | The Session is a handle to the complete state of a compilation
    -- session.  A compilation session consists of a set of modules
    -- constituting the current program or library, the context for
    -- interactive evaluation, and various caches.
    data Session = Session !(IORef HscEnv)

    instance Applicative Ghc where
      pure :: forall a. a -> Ghc a
    pure a
    a = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ \Session
    _ -> forall (m :: * -> *) a. Monad m => a -> m a
    return a
    a
      Ghc (a -> b)
    g <*> :: forall a b. Ghc (a -> b) -> Ghc a -> Ghc b
    <*> Ghc a
    m = do a -> b
    f <- Ghc (a -> b)
    g; a
    a <- Ghc a
    m; forall (m :: * -> *) a. Monad m => a -> m a
    return (a -> b
    f a
    a)

    instance Monad Ghc where
      Ghc a
    m >>= :: forall a b. Ghc a -> (a -> Ghc b) -> Ghc b
    >>= a -> Ghc b
    g  = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ \Session
    s -> do a
    a <- forall a. Ghc a -> Session -> IO a
    unGhc Ghc a
    m Session
    s; forall a. Ghc a -> Session -> IO a
    unGhc (a -> Ghc b
    g a
    a) Session
    s

    instance MonadIO Ghc where
      liftIO :: forall a. IO a -> Ghc a
    liftIO IO a
    ioA = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ \Session
    _ -> IO a
    ioA

    instance MonadFix Ghc where
      mfix :: forall a. (a -> Ghc a) -> Ghc a
    mfix a -> Ghc a
    f = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ \Session
    s -> forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
    mfix (\a
    x -> forall a. Ghc a -> Session -> IO a
    unGhc (a -> Ghc a
    f a
    x) Session
    s)

    instance HasDynFlags Ghc where
      getDynFlags :: Ghc DynFlags
    getDynFlags = forall (m :: * -> *). GhcMonad m => m DynFlags
    getSessionDynFlags

    instance HasLogger Ghc where
      getLogger :: Ghc Logger
    getLogger = HscEnv -> Logger
    hsc_logger forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall (m :: * -> *). GhcMonad m => m HscEnv
    getSession

    instance GhcMonad Ghc where
      getSession :: Ghc HscEnv
    getSession = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ \(Session IORef HscEnv
    r) -> forall a. IORef a -> IO a
    readIORef IORef HscEnv
    r
      setSession :: HscEnv -> Ghc ()
    setSession HscEnv
    s' = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ \(Session IORef HscEnv
    r) -> forall a. IORef a -> a -> IO ()
    writeIORef IORef HscEnv
    r HscEnv
    s'

    -- | Reflect a computation in the 'Ghc' monad into the 'IO' monad.
    --
    -- You can use this to call functions returning an action in the 'Ghc' monad
    -- inside an 'IO' action.  This is needed for some (too restrictive) callback
    -- arguments of some library functions:
    --
    -- > libFunc :: String -> (Int -> IO a) -> IO a
    -- > ghcFunc :: Int -> Ghc a
    -- >
    -- > ghcFuncUsingLibFunc :: String -> Ghc a -> Ghc a
    -- > ghcFuncUsingLibFunc str =
    -- >   reifyGhc $ \s ->
    -- >     libFunc $ \i -> do
    -- >       reflectGhc (ghcFunc i) s
    --
    reflectGhc :: Ghc a -> Session -> IO a
    reflectGhc :: forall a. Ghc a -> Session -> IO a
    reflectGhc Ghc a
    m = forall a. Ghc a -> Session -> IO a
    unGhc Ghc a
    m

    -- > Dual to 'reflectGhc'.  See its documentation.
    reifyGhc :: (Session -> IO a) -> Ghc a
    reifyGhc :: forall a. (Session -> IO a) -> Ghc a
    reifyGhc Session -> IO a
    act = forall a. (Session -> IO a) -> Ghc a
    Ghc forall a b. (a -> b) -> a -> b
    $ Session -> IO a
    act

    -- -----------------------------------------------------------------------------
    -- | A monad transformer to add GHC specific features to another monad.
    --
    -- Note that the wrapped monad must support IO and handling of exceptions.
    newtype GhcT m a = GhcT { forall (m :: * -> *) a. GhcT m a -> Session -> m a
    unGhcT :: Session -> m a }
      deriving (forall a b. a -> GhcT m b -> GhcT m a
    forall a b. (a -> b) -> GhcT m a -> GhcT m b
    forall (m :: * -> *) a b. Functor m => a -> GhcT m b -> GhcT m a
    forall (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> GhcT m a -> GhcT m b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    <$ :: forall a b. a -> GhcT m b -> GhcT m a
    $c<$ :: forall (m :: * -> *) a b. Functor m => a -> GhcT m b -> GhcT m a
    fmap :: forall a b. (a -> b) -> GhcT m a -> GhcT m b
    $cfmap :: forall (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> GhcT m a -> GhcT m b
    Functor)
      deriving (forall e a. Exception e => e -> GhcT m a
    forall (m :: * -> *).
    Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
    forall {m :: * -> *}. MonadThrow m => Monad (GhcT m)
    forall (m :: * -> *) e a.
    (MonadThrow m, Exception e) =>
    e -> GhcT m a
    throwM :: forall e a. Exception e => e -> GhcT m a
    $cthrowM :: forall (m :: * -> *) e a.
    (MonadThrow m, Exception e) =>
    e -> GhcT m a
    MonadThrow, forall e a. Exception e => GhcT m a -> (e -> GhcT m a) -> GhcT m a
    forall (m :: * -> *).
    MonadThrow m
    -> (forall e a. Exception e => m a -> (e -> m a) -> m a)
    -> MonadCatch m
    forall {m :: * -> *}. MonadCatch m => MonadThrow (GhcT m)
    forall (m :: * -> *) e a.
    (MonadCatch m, Exception e) =>
    GhcT m a -> (e -> GhcT m a) -> GhcT m a
    catch :: forall e a. Exception e => GhcT m a -> (e -> GhcT m a) -> GhcT m a
    $ccatch :: forall (m :: * -> *) e a.
    (MonadCatch m, Exception e) =>
    GhcT m a -> (e -> GhcT m a) -> GhcT m a
    MonadCatch, forall b.
    ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b
    forall a b c.
    GhcT m a
    -> (a -> ExitCase b -> GhcT m c)
    -> (a -> GhcT m b)
    -> GhcT m (b, c)
    forall {m :: * -> *}. MonadMask m => MonadCatch (GhcT m)
    forall (m :: * -> *) b.
    MonadMask m =>
    ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b
    forall (m :: * -> *) a b c.
    MonadMask m =>
    GhcT m a
    -> (a -> ExitCase b -> GhcT m c)
    -> (a -> GhcT m b)
    -> GhcT m (b, c)
    forall (m :: * -> *).
    MonadCatch m
    -> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
    -> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
    -> (forall a b c.
        m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
    -> MonadMask m
    generalBracket :: forall a b c.
    GhcT m a
    -> (a -> ExitCase b -> GhcT m c)
    -> (a -> GhcT m b)
    -> GhcT m (b, c)
    $cgeneralBracket :: forall (m :: * -> *) a b c.
    MonadMask m =>
    GhcT m a
    -> (a -> ExitCase b -> GhcT m c)
    -> (a -> GhcT m b)
    -> GhcT m (b, c)
    uninterruptibleMask :: forall b.
    ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b
    $cuninterruptibleMask :: forall (m :: * -> *) b.
    MonadMask m =>
    ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b
    mask :: forall b.
    ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b
    $cmask :: forall (m :: * -> *) b.
    MonadMask m =>
    ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b
    MonadMask) via (ReaderT Session m)

    liftGhcT :: m a -> GhcT m a
    liftGhcT :: forall (m :: * -> *) a. m a -> GhcT m a
    liftGhcT m a
    m = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \Session
    _ -> m a
    m

    instance Applicative m => Applicative (GhcT m) where
      pure :: forall a. a -> GhcT m a
    pure a
    x  = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \Session
    _ -> forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    x
      GhcT m (a -> b)
    g <*> :: forall a b. GhcT m (a -> b) -> GhcT m a -> GhcT m b
    <*> GhcT m a
    m = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \Session
    s -> forall (m :: * -> *) a. GhcT m a -> Session -> m a
    unGhcT GhcT m (a -> b)
    g Session
    s forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> forall (m :: * -> *) a. GhcT m a -> Session -> m a
    unGhcT GhcT m a
    m Session
    s

    instance Monad m => Monad (GhcT m) where
      GhcT m a
    m >>= :: forall a b. GhcT m a -> (a -> GhcT m b) -> GhcT m b
    >>= a -> GhcT m b
    k  = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \Session
    s -> do a
    a <- forall (m :: * -> *) a. GhcT m a -> Session -> m a
    unGhcT GhcT m a
    m Session
    s; forall (m :: * -> *) a. GhcT m a -> Session -> m a
    unGhcT (a -> GhcT m b
    k a
    a) Session
    s

    instance MonadIO m => MonadIO (GhcT m) where
      liftIO :: forall a. IO a -> GhcT m a
    liftIO IO a
    ioA = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \Session
    _ -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO a
    ioA

    instance MonadIO m => HasDynFlags (GhcT m) where
      getDynFlags :: GhcT m DynFlags
    getDynFlags = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \(Session IORef HscEnv
    r) -> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM HscEnv -> DynFlags
    hsc_dflags (forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ forall a. IORef a -> IO a
    readIORef IORef HscEnv
    r)

    instance MonadIO m => HasLogger (GhcT m) where
      getLogger :: GhcT m Logger
    getLogger = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \(Session IORef HscEnv
    r) -> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM HscEnv -> Logger
    hsc_logger (forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ forall a. IORef a -> IO a
    readIORef IORef HscEnv
    r)

    instance ExceptionMonad m => GhcMonad (GhcT m) where
      getSession :: GhcT m HscEnv
    getSession = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \(Session IORef HscEnv
    r) -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ forall a. IORef a -> IO a
    readIORef IORef HscEnv
    r
      setSession :: HscEnv -> GhcT m ()
    setSession HscEnv
    s' = forall (m :: * -> *) a. (Session -> m a) -> GhcT m a
    GhcT forall a b. (a -> b) -> a -> b
    $ \(Session IORef HscEnv
    r) -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ forall a. IORef a -> a -> IO ()
    writeIORef IORef HscEnv
    r HscEnv
    s'

    -- | Print the error message and all warnings.  Useful inside exception
    --   handlers.  Clears warnings after printing.
    printException :: GhcMonad m => SourceError -> m ()
    printException :: forall (m :: * -> *). GhcMonad m => SourceError -> m ()
    printException SourceError
    err = do
      DynFlags
    dflags <- forall (m :: * -> *). GhcMonad m => m DynFlags
    getSessionDynFlags
      Logger
    logger <- forall (m :: * -> *). HasLogger m => m Logger
    getLogger
      forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO forall a b. (a -> b) -> a -> b
    $ forall a.
    RenderableDiagnostic a =>
    Logger -> DynFlags -> Bag (MsgEnvelope a) -> IO ()
    printBagOfErrors Logger
    logger DynFlags
    dflags (SourceError -> WarningMessages
    srcErrorMessages SourceError
    err)

    -- | A function called to log warnings and errors.
    type WarnErrLogger = forall m. GhcMonad m => Maybe SourceError -> m ()

    defaultWarnErrLogger :: WarnErrLogger
    defaultWarnErrLogger :: WarnErrLogger
    defaultWarnErrLogger Maybe SourceError
    Nothing  = forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    defaultWarnErrLogger (Just SourceError
    e) = forall (m :: * -> *). GhcMonad m => SourceError -> m ()
    printException SourceError
    e