    {-
    (c) The University of Glasgow 2006
    (c) The GRASP Project, Glasgow University, 1992-2000

    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE ScopedTypeVariables, LambdaCase #-}

    #include <ghcautoconf.h>

    -- | Defines basic functions for printing error messages.
    --
    -- It's hard to put these functions anywhere else without causing
    -- some unnecessary loops in the module dependency graph.
    module GHC.Utils.Panic
       ( -- * GHC exception type
         GhcException(..)
       , showGhcException
       , showGhcExceptionUnsafe
       , throwGhcException
       , throwGhcExceptionIO
       , handleGhcException

         -- * Command error throwing patterns
       , pprPanic
       , panicDoc
       , sorryDoc
       , pgmErrorDoc
         -- ** Assertions
       , assertPprPanic
       , assertPpr
       , assertPprMaybe
       , assertPprM
       , massertPpr

         -- * Call stacks
       , callStackDoc
       , prettyCallStackDoc

         -- * Exception utilities
       , Exception.Exception(..)
       , showException
       , safeShowException
       , try
       , tryMost
       , throwTo
       , withSignalHandlers
       , module GHC.Utils.Panic.Plain
       )
    where

    import GHC.Prelude.Basic
    import GHC.Stack

    import GHC.Utils.Outputable
    import GHC.Utils.Panic.Plain
    import GHC.Utils.Constants

    import GHC.Utils.Exception as Exception

    import Control.Monad.IO.Class
    import qualified Control.Monad.Catch as MC
    import Control.Concurrent
    import Data.Typeable      ( cast )
    import System.IO.Unsafe

    #if !defined(mingw32_HOST_OS)
    import System.Posix.Signals as S
    #endif

    #if defined(mingw32_HOST_OS)
    import GHC.ConsoleHandler as S
    #endif

    import System.Mem.Weak  ( deRefWeak )

    -- | GHC's own exception type
    --   error messages all take the form:
    --
    --  @
    --      \<location>: \<error>
    --  @
    --
    --   If the location is on the command line, or in GHC itself, then
    --   \<location>="ghc".  All of the error types below correspond to
    --   a \<location> of "ghc", except for ProgramError (where the string is
    --  assumed to contain a location already, so we don't print one).

    data GhcException
      -- | Some other fatal signal (SIGHUP,SIGTERM)
      = Signal Int

      -- | Prints the short usage msg after the error
      | UsageError   String

      -- | A problem with the command line arguments, but don't print usage.
      | CmdLineError String

      -- | The 'impossible' happened.
      | Panic        String
      | PprPanic     String SDoc

      -- | The user tickled something that's known not to work yet,
      --   but we're not counting it as a bug.
      | Sorry        String
      | PprSorry     String SDoc

      -- | An installation problem.
      | InstallationError String

      -- | An error in the user's code, probably.
      | ProgramError    String
      | PprProgramError String SDoc

    instance Exception GhcException where
      fromException :: SomeException -> Maybe GhcException
    fromException (SomeException e
    e)
        | Just GhcException
    ge <- e -> Maybe GhcException
    forall a b. (Typeable a, Typeable b) => a -> Maybe b
    cast e
    e = GhcException -> Maybe GhcException
    forall a. a -> Maybe a
    Just GhcException
    ge
        | Just PlainGhcException
    pge <- e -> Maybe PlainGhcException
    forall a b. (Typeable a, Typeable b) => a -> Maybe b
    cast e
    e = GhcException -> Maybe GhcException
    forall a. a -> Maybe a
    Just (GhcException -> Maybe GhcException)
    -> GhcException -> Maybe GhcException
    forall a b. (a -> b) -> a -> b
    $
            case PlainGhcException
    pge of
              PlainSignal Int
    n -> Int -> GhcException
    Signal Int
    n
              PlainUsageError String
    str -> String -> GhcException
    UsageError String
    str
              PlainCmdLineError String
    str -> String -> GhcException
    CmdLineError String
    str
              PlainPanic String
    str -> String -> GhcException
    Panic String
    str
              PlainSorry String
    str -> String -> GhcException
    Sorry String
    str
              PlainInstallationError String
    str -> String -> GhcException
    InstallationError String
    str
              PlainProgramError String
    str -> String -> GhcException
    ProgramError String
    str
        | Bool
    otherwise = Maybe GhcException
    forall a. Maybe a
    Nothing

      -- Explicitly omit ExceptionContext since we generally don't
      -- want backtraces and other context in GHC's user errors.
      displayException :: GhcException -> String
    displayException GhcException
    exc = GhcException -> ShowS
    showGhcExceptionUnsafe GhcException
    exc String
    ""

    instance Show GhcException where
      showsPrec :: Int -> GhcException -> ShowS
    showsPrec Int
    _ GhcException
    e = GhcException -> ShowS
    showGhcExceptionUnsafe GhcException
    e

    -- | Show an exception as a string.
    showException :: Exception e => e -> String
    showException :: forall e. Exception e => e -> String
    showException = e -> String
    forall a. Show a => a -> String
    show

    -- | Show an exception which can possibly throw other exceptions.
    -- Used when displaying exception thrown within TH code.
    safeShowException :: Exception e => e -> IO String
    safeShowException :: forall e. Exception e => e -> IO String
    safeShowException e
    e = do
        -- ensure the whole error message is evaluated inside try
        r <- IO String -> IO (Either SomeException String)
    forall e a. Exception e => IO a -> IO (Either e a)
    try (String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String -> IO String) -> String -> IO String
    forall a b. (a -> b) -> a -> b
    $! ShowS
    forall {a}. [a] -> [a]
    forceList (e -> String
    forall e. Exception e => e -> String
    showException e
    e))
        case r of
            Right String
    msg -> String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    msg
            Left SomeException
    e' -> SomeException -> IO String
    forall e. Exception e => e -> IO String
    safeShowException (SomeException
    e' :: SomeException)
        where
            forceList :: [a] -> [a]
    forceList [] = []
            forceList xs :: [a]
    xs@(a
    x : [a]
    xt) = a
    x a -> [a] -> [a]
    forall a b. a -> b -> b
    `seq` [a] -> [a]
    forceList [a]
    xt [a] -> [a] -> [a]
    forall a b. a -> b -> b
    `seq` [a]
    xs

    -- | Append a description of the given exception to this string.
    --
    -- Note that this uses 'defaultSDocContext', which doesn't use the options
    -- set by the user via DynFlags.
    showGhcExceptionUnsafe :: GhcException -> ShowS
    showGhcExceptionUnsafe :: GhcException -> ShowS
    showGhcExceptionUnsafe = SDocContext -> GhcException -> ShowS
    showGhcException SDocContext
    defaultSDocContext

    -- | Append a description of the given exception to this string.
    showGhcException :: SDocContext -> GhcException -> ShowS
    showGhcException :: SDocContext -> GhcException -> ShowS
    showGhcException SDocContext
    ctx = PlainGhcException -> ShowS
    showPlainGhcException (PlainGhcException -> ShowS)
    -> (GhcException -> PlainGhcException) -> GhcException -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . \case
      Signal Int
    n -> Int -> PlainGhcException
    PlainSignal Int
    n
      UsageError String
    str -> String -> PlainGhcException
    PlainUsageError String
    str
      CmdLineError String
    str -> String -> PlainGhcException
    PlainCmdLineError String
    str
      Panic String
    str -> String -> PlainGhcException
    PlainPanic String
    str
      Sorry String
    str -> String -> PlainGhcException
    PlainSorry String
    str
      InstallationError String
    str -> String -> PlainGhcException
    PlainInstallationError String
    str
      ProgramError String
    str -> String -> PlainGhcException
    PlainProgramError String
    str

      PprPanic String
    str SDoc
    sdoc -> String -> PlainGhcException
    PlainPanic (String -> PlainGhcException) -> String -> PlainGhcException
    forall a b. (a -> b) -> a -> b
    $
          [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [String
    str, String
    "\n\n", SDocContext -> SDoc -> String
    renderWithContext SDocContext
    ctx SDoc
    sdoc]
      PprSorry String
    str SDoc
    sdoc -> String -> PlainGhcException
    PlainProgramError (String -> PlainGhcException) -> String -> PlainGhcException
    forall a b. (a -> b) -> a -> b
    $
          [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [String
    str, String
    "\n\n", SDocContext -> SDoc -> String
    renderWithContext SDocContext
    ctx SDoc
    sdoc]
      PprProgramError String
    str SDoc
    sdoc -> String -> PlainGhcException
    PlainProgramError (String -> PlainGhcException) -> String -> PlainGhcException
    forall a b. (a -> b) -> a -> b
    $
          [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [String
    str, String
    "\n\n", SDocContext -> SDoc -> String
    renderWithContext SDocContext
    ctx SDoc
    sdoc]

    throwGhcException :: GhcException -> a
    throwGhcException :: forall a. GhcException -> a
    throwGhcException = GhcException -> a
    forall a e. (HasCallStack, Exception e) => e -> a
    Exception.throw

    throwGhcExceptionIO :: GhcException -> IO a
    throwGhcExceptionIO :: forall a. GhcException -> IO a
    throwGhcExceptionIO = GhcException -> IO a
    forall e a. (HasCallStack, Exception e) => e -> IO a
    Exception.throwIO

    handleGhcException :: ExceptionMonad m => (GhcException -> m a) -> m a -> m a
    handleGhcException :: forall (m :: * -> *) a.
    ExceptionMonad m =>
    (GhcException -> m a) -> m a -> m a
    handleGhcException = (GhcException -> m a) -> m a -> m a
    forall (m :: * -> *) e a.
    (HasCallStack, MonadCatch m, Exception e) =>
    (e -> m a) -> m a -> m a
    MC.handle

    -- | Throw an exception saying "bug in GHC" with a callstack
    pprPanic :: HasCallStack => String -> SDoc -> a
    pprPanic :: forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    s SDoc
    doc = String -> SDoc -> a
    forall a. String -> SDoc -> a
    panicDoc String
    s (SDoc
    doc SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$ SDoc
    HasCallStack => SDoc
    callStackDoc)

    -- | Throw an exception saying "bug in GHC"
    panicDoc :: String -> SDoc -> a
    panicDoc :: forall a. String -> SDoc -> a
    panicDoc String
    x SDoc
    doc = GhcException -> a
    forall a. GhcException -> a
    throwGhcException (String -> SDoc -> GhcException
    PprPanic String
    x SDoc
    doc)

    -- | Throw an exception saying "this isn't finished yet"
    sorryDoc :: String -> SDoc -> a
    sorryDoc :: forall a. String -> SDoc -> a
    sorryDoc String
    x SDoc
    doc = GhcException -> a
    forall a. GhcException -> a
    throwGhcException (String -> SDoc -> GhcException
    PprSorry String
    x SDoc
    doc)

    -- | Throw an exception saying "bug in pgm being compiled" (used for unusual program errors)
    pgmErrorDoc :: String -> SDoc -> a
    pgmErrorDoc :: forall a. String -> SDoc -> a
    pgmErrorDoc String
    x SDoc
    doc = GhcException -> a
    forall a. GhcException -> a
    throwGhcException (String -> SDoc -> GhcException
    PprProgramError String
    x SDoc
    doc)

    -- | Like try, but pass through UserInterrupt and Panic exceptions.
    --   Used when we want soft failures when reading interface files, for example.
    --   TODO: I'm not entirely sure if this is catching what we really want to catch
    tryMost :: IO a -> IO (Either SomeException a)
    tryMost :: forall a. IO a -> IO (Either SomeException a)
    tryMost IO a
    action = do r <- IO a -> IO (Either SomeException a)
    forall e a. Exception e => IO a -> IO (Either e a)
    try IO a
    action
                        case r of
                            Left SomeException
    se ->
                                case SomeException -> Maybe GhcException
    forall e. Exception e => SomeException -> Maybe e
    fromException SomeException
    se of
                                    -- Some GhcException's we rethrow,
                                    Just (Signal Int
    _)  -> SomeException -> IO (Either SomeException a)
    forall e a. (HasCallStack, Exception e) => e -> IO a
    throwIO SomeException
    se
                                    Just (Panic String
    _)   -> SomeException -> IO (Either SomeException a)
    forall e a. (HasCallStack, Exception e) => e -> IO a
    throwIO SomeException
    se
                                    -- others we return
                                    Just GhcException
    _           -> Either SomeException a -> IO (Either SomeException a)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SomeException -> Either SomeException a
    forall a b. a -> Either a b
    Left SomeException
    se)
                                    Maybe GhcException
    Nothing ->
                                        case SomeException -> Maybe IOException
    forall e. Exception e => SomeException -> Maybe e
    fromException SomeException
    se of
                                            -- All IOExceptions are returned
                                            Just (IOException
    _ :: IOException) ->
                                                Either SomeException a -> IO (Either SomeException a)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SomeException -> Either SomeException a
    forall a b. a -> Either a b
    Left SomeException
    se)
                                            -- Anything else is rethrown
                                            Maybe IOException
    Nothing -> SomeException -> IO (Either SomeException a)
    forall e a. (HasCallStack, Exception e) => e -> IO a
    throwIO SomeException
    se
                            Right a
    v -> Either SomeException a -> IO (Either SomeException a)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a -> Either SomeException a
    forall a b. b -> Either a b
    Right a
    v)

    -- | We use reference counting for signal handlers
    {-# NOINLINE signalHandlersRefCount #-}
    #if !defined(mingw32_HOST_OS)
    signalHandlersRefCount :: MVar (Word, Maybe (S.Handler,S.Handler
                                                ,S.Handler,S.Handler))
    #else
    signalHandlersRefCount :: MVar (Word, Maybe S.Handler)
    #endif
    signalHandlersRefCount :: MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    signalHandlersRefCount = IO (MVar (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    forall a. IO a -> a
    unsafePerformIO (IO (MVar (Word, Maybe (Handler, Handler, Handler, Handler)))
     -> MVar (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> IO (MVar (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    forall a b. (a -> b) -> a -> b
    $ (Word, Maybe (Handler, Handler, Handler, Handler))
    -> IO (MVar (Word, Maybe (Handler, Handler, Handler, Handler)))
    forall a. a -> IO (MVar a)
    newMVar (Word
    0,Maybe (Handler, Handler, Handler, Handler)
    forall a. Maybe a
    Nothing)

    -- | Temporarily install standard signal handlers for catching ^C, which just
    -- throw an exception in the current thread.
    withSignalHandlers :: ExceptionMonad m => m a -> m a
    #if !defined(HAVE_SIGNAL_H)
    -- No signal functionality exist on the host platform (e.g. on
    -- wasm32-wasi), so don't attempt to set up signal handlers
    withSignalHandlers = id
    #else
    withSignalHandlers :: forall (m :: * -> *) a. ExceptionMonad m => m a -> m a
    withSignalHandlers m a
    act = do
      main_thread <- IO ThreadId -> m ThreadId
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO ThreadId
    myThreadId
      wtid <- liftIO (mkWeakThreadId main_thread)

      let
          interrupt = do
            r <- Weak ThreadId -> IO (Maybe ThreadId)
    forall v. Weak v -> IO (Maybe v)
    deRefWeak Weak ThreadId
    wtid
            case r of
              Maybe ThreadId
    Nothing -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
              Just ThreadId
    t  -> ThreadId -> AsyncException -> IO ()
    forall e. Exception e => ThreadId -> e -> IO ()
    throwTo ThreadId
    t AsyncException
    UserInterrupt

    #if !defined(mingw32_HOST_OS)
      let installHandlers = do
            let installHandler' :: CInt -> Handler -> IO Handler
    installHandler' CInt
    a Handler
    b = CInt -> Handler -> Maybe SignalSet -> IO Handler
    installHandler CInt
    a Handler
    b Maybe SignalSet
    forall a. Maybe a
    Nothing
            hdlQUIT <- CInt -> Handler -> IO Handler
    installHandler' CInt
    sigQUIT  (IO () -> Handler
    Catch IO ()
    interrupt)
            hdlINT  <- installHandler' sigINT   (Catch interrupt)
            -- see #3656; in the future we should install these automatically for
            -- all Haskell programs in the same way that we install a ^C handler.
            let fatal_signal CInt
    n = ThreadId -> GhcException -> IO ()
    forall e. Exception e => ThreadId -> e -> IO ()
    throwTo ThreadId
    main_thread (Int -> GhcException
    Signal (CInt -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral CInt
    n))
            hdlHUP  <- installHandler' sigHUP   (Catch (fatal_signal sigHUP))
            hdlTERM <- installHandler' sigTERM  (Catch (fatal_signal sigTERM))
            return (hdlQUIT,hdlINT,hdlHUP,hdlTERM)

      let uninstallHandlers (Handler
    hdlQUIT,Handler
    hdlINT,Handler
    hdlHUP,Handler
    hdlTERM) = do
            _ <- CInt -> Handler -> Maybe SignalSet -> IO Handler
    installHandler CInt
    sigQUIT  Handler
    hdlQUIT Maybe SignalSet
    forall a. Maybe a
    Nothing
            _ <- installHandler sigINT   hdlINT  Nothing
            _ <- installHandler sigHUP   hdlHUP  Nothing
            _ <- installHandler sigTERM  hdlTERM Nothing
            return ()
    #else
      -- GHC 6.3+ has support for console events on Windows
      -- NOTE: running GHCi under a bash shell for some reason requires
      -- you to press Ctrl-Break rather than Ctrl-C to provoke
      -- an interrupt.  Ctrl-C is getting blocked somewhere, I don't know
      -- why --SDM 17/12/2004
      let sig_handler ControlC = interrupt
          sig_handler Break    = interrupt
          sig_handler _        = return ()

      let installHandlers   = installHandler (Catch sig_handler)
      let uninstallHandlers = installHandler -- directly install the old handler
    #endif

      -- install signal handlers if necessary
      let mayInstallHandlers = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    -> ((Word, Maybe (Handler, Handler, Handler, Handler))
        -> IO (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> IO ()
    forall a. MVar a -> (a -> IO a) -> IO ()
    modifyMVar_ MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    signalHandlersRefCount (((Word, Maybe (Handler, Handler, Handler, Handler))
      -> IO (Word, Maybe (Handler, Handler, Handler, Handler)))
     -> IO ())
    -> ((Word, Maybe (Handler, Handler, Handler, Handler))
        -> IO (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \case
            (Word
    0,Maybe (Handler, Handler, Handler, Handler)
    Nothing)     -> do
              hdls <- IO (Handler, Handler, Handler, Handler)
    installHandlers
              return (1,Just hdls)
            (Word
    c,Maybe (Handler, Handler, Handler, Handler)
    oldHandlers) -> (Word, Maybe (Handler, Handler, Handler, Handler))
    -> IO (Word, Maybe (Handler, Handler, Handler, Handler))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Word
    cWord -> Word -> Word
    forall a. Num a => a -> a -> a
    +Word
    1,Maybe (Handler, Handler, Handler, Handler)
    oldHandlers)

      -- uninstall handlers if necessary
      let mayUninstallHandlers = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    -> ((Word, Maybe (Handler, Handler, Handler, Handler))
        -> IO (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> IO ()
    forall a. MVar a -> (a -> IO a) -> IO ()
    modifyMVar_ MVar (Word, Maybe (Handler, Handler, Handler, Handler))
    signalHandlersRefCount (((Word, Maybe (Handler, Handler, Handler, Handler))
      -> IO (Word, Maybe (Handler, Handler, Handler, Handler)))
     -> IO ())
    -> ((Word, Maybe (Handler, Handler, Handler, Handler))
        -> IO (Word, Maybe (Handler, Handler, Handler, Handler)))
    -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \case
            (Word
    1,Just (Handler, Handler, Handler, Handler)
    hdls)   -> do
              _ <- (Handler, Handler, Handler, Handler) -> IO ()
    uninstallHandlers (Handler, Handler, Handler, Handler)
    hdls
              return (0,Nothing)
            (Word
    c,Maybe (Handler, Handler, Handler, Handler)
    oldHandlers) -> (Word, Maybe (Handler, Handler, Handler, Handler))
    -> IO (Word, Maybe (Handler, Handler, Handler, Handler))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Word
    cWord -> Word -> Word
    forall a. Num a => a -> a -> a
    -Word
    1,Maybe (Handler, Handler, Handler, Handler)
    oldHandlers)

      mayInstallHandlers
      act `MC.finally` mayUninstallHandlers
    #endif

    callStackDoc :: HasCallStack => SDoc
    callStackDoc :: HasCallStack => SDoc
    callStackDoc = CallStack -> SDoc
    prettyCallStackDoc CallStack
    HasCallStack => CallStack
    callStack

    prettyCallStackDoc :: CallStack -> SDoc
    prettyCallStackDoc :: CallStack -> SDoc
    prettyCallStackDoc CallStack
    cs =
        SDoc -> Int -> SDoc -> SDoc
    hang (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Call stack:")
           Int
    4 ([SDoc] -> SDoc
    forall doc. IsDoc doc => [doc] -> doc
    vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
    forall a b. (a -> b) -> a -> b
    $ (String -> SDoc) -> [String] -> [SDoc]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> SDoc
    forall doc. IsLine doc => String -> doc
    text ([String] -> [SDoc]) -> [String] -> [SDoc]
    forall a b. (a -> b) -> a -> b
    $ String -> [String]
    lines (CallStack -> String
    prettyCallStack CallStack
    cs))

    -- | Panic with an assertion failure, recording the given file and
    -- line number. Should typically be accessed with the ASSERT family of macros
    assertPprPanic :: HasCallStack => SDoc -> a
    assertPprPanic :: forall a. HasCallStack => SDoc -> a
    assertPprPanic SDoc
    msg = (HasCallStack => a) -> a
    forall a. HasCallStack => (HasCallStack => a) -> a
    withFrozenCallStack (String -> SDoc -> a
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "ASSERT failed!" SDoc
    msg)

    assertPpr :: HasCallStack => Bool -> SDoc -> a -> a
    {-# INLINE assertPpr #-}
    assertPpr :: forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr Bool
    cond SDoc
    msg a
    a =
      if Bool
    debugIsOn Bool -> Bool -> Bool
    && Bool -> Bool
    not Bool
    cond
        then (HasCallStack => a) -> a
    forall a. HasCallStack => (HasCallStack => a) -> a
    withFrozenCallStack (SDoc -> a
    forall a. HasCallStack => SDoc -> a
    assertPprPanic SDoc
    msg)
        else a
    a

    assertPprMaybe :: HasCallStack => Maybe SDoc -> a -> a
    {-# INLINE assertPprMaybe #-}
    assertPprMaybe :: forall a. HasCallStack => Maybe SDoc -> a -> a
    assertPprMaybe Maybe SDoc
    mb_msg a
    a
      | Bool
    debugIsOn, Just SDoc
    msg <- Maybe SDoc
    mb_msg = (HasCallStack => a) -> a
    forall a. HasCallStack => (HasCallStack => a) -> a
    withFrozenCallStack (SDoc -> a
    forall a. HasCallStack => SDoc -> a
    assertPprPanic SDoc
    msg)
      | Bool
    otherwise                     = a
    a

    massertPpr :: (HasCallStack, Applicative m) => Bool -> SDoc -> m ()
    {-# INLINE massertPpr #-}
    massertPpr :: forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr Bool
    cond SDoc
    msg = (HasCallStack => m ()) -> m ()
    forall a. HasCallStack => (HasCallStack => a) -> a
    withFrozenCallStack (Bool -> SDoc -> m () -> m ()
    forall a. HasCallStack => Bool -> SDoc -> a -> a
    assertPpr Bool
    cond SDoc
    msg (() -> m ()
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()))

    assertPprM :: (HasCallStack, Monad m) => m Bool -> SDoc -> m ()
    {-# INLINE assertPprM #-}
    assertPprM :: forall (m :: * -> *).
    (HasCallStack, Monad m) =>
    m Bool -> SDoc -> m ()
    assertPprM m Bool
    mcond SDoc
    msg = (HasCallStack => m ()) -> m ()
    forall a. HasCallStack => (HasCallStack => a) -> a
    withFrozenCallStack (m Bool
    mcond m Bool -> (Bool -> m ()) -> m ()
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \Bool
    cond -> Bool -> SDoc -> m ()
    forall (m :: * -> *).
    (HasCallStack, Applicative m) =>
    Bool -> SDoc -> m ()
    massertPpr Bool
    cond SDoc
    msg)