content: {-# LANGUAGE NoImplicitPrelude #-}
  {-# LANGUAGE ConstraintKinds   #-}
  {-# LANGUAGE ImplicitParams    #-}
  {-# LANGUAGE KindSignatures    #-}
  {-# LANGUAGE PolyKinds         #-}
  {-# LANGUAGE RankNTypes        #-}
  {-# LANGUAGE Trustworthy       #-}
  
  {-# OPTIONS_HADDOCK hide #-}
  -- we hide this module from haddock to enforce GHC.Stack as the main
  -- access point.
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  GHC.Stack.Types
  -- Copyright   :  (c) The University of Glasgow 2015
  -- License     :  see libraries/ghc-prim/LICENSE
  --
  -- Maintainer  :  cvs-ghc@haskell.org
  -- Stability   :  internal
  -- Portability :  non-portable (GHC Extensions)
  --
  -- type definitions for implicit call-stacks.
  -- Use "GHC.Stack" from the base package instead of importing this
  -- module directly.
  --
  -----------------------------------------------------------------------------
  
  module GHC.Stack.Types (
      -- * Implicit call stacks
      CallStack(..), HasCallStack,
      emptyCallStack, freezeCallStack, fromCallSiteList,
      getCallStack, pushCallStack,
  
      -- * Source locations
      SrcLoc(..)
    ) where
  
  {-
  Ideally these would live in GHC.Stack but sadly they can't due to this
  import cycle,
  
      Module imports form a cycle:
             module ‘GHC.Base’ (libraries/base/GHC/Base.hs)
            imports ‘GHC.Err’ (libraries/base/GHC/Err.hs)
      which imports ‘GHC.Stack’ (libraries/base/dist-install/build/GHC/Stack.hs)
      which imports ‘GHC.Base‘ (libraries/base/GHC/Base.hs)
  -}
  
  import GHC.Classes (Eq)
  import GHC.Types (Char, Int)
  
  -- Make implicit dependency known to build system
  import GHC.Tuple ()
  import GHC.Integer ()
  
  ----------------------------------------------------------------------
  -- Explicit call-stacks built via ImplicitParams
  ----------------------------------------------------------------------
  
  -- | Request a CallStack.
  --
  -- NOTE: The implicit parameter @?callStack :: CallStack@ is an
  -- implementation detail and __should not__ be considered part of the
  -- 'CallStack' API, we may decide to change the implementation in the
  -- future.
  --
  -- @since 4.9.0.0
  type HasCallStack = (?callStack :: CallStack)
  
  -- | 'CallStack's are a lightweight method of obtaining a
  -- partial call-stack at any point in the program.
  --
  -- A function can request its call-site with the 'HasCallStack' constraint.
  -- For example, we can define
  --
  -- @
  -- putStrLnWithCallStack :: HasCallStack => String -> IO ()
  -- @
  --
  -- as a variant of @putStrLn@ that will get its call-site and print it,
  -- along with the string given as argument. We can access the
  -- call-stack inside @putStrLnWithCallStack@ with 'GHC.Stack.callStack'.
  --
  -- @
  -- putStrLnWithCallStack :: HasCallStack => String -> IO ()
  -- putStrLnWithCallStack msg = do
  --   putStrLn msg
  --   putStrLn (prettyCallStack callStack)
  -- @
  --
  -- Thus, if we call @putStrLnWithCallStack@ we will get a formatted call-stack
  -- alongside our string.
  --
  --
  -- >>> putStrLnWithCallStack "hello"
  -- hello
  -- CallStack (from HasCallStack):
  --   putStrLnWithCallStack, called at <interactive>:2:1 in interactive:Ghci1
  --
  --
  -- GHC solves 'HasCallStack' constraints in three steps:
  --
  -- 1. If there is a 'CallStack' in scope -- i.e. the enclosing function
  --    has a 'HasCallStack' constraint -- GHC will append the new
  --    call-site to the existing 'CallStack'.
  --
  -- 2. If there is no 'CallStack' in scope -- e.g. in the GHCi session
  --    above -- and the enclosing definition does not have an explicit
  --    type signature, GHC will infer a 'HasCallStack' constraint for the
  --    enclosing definition (subject to the monomorphism restriction).
  --
  -- 3. If there is no 'CallStack' in scope and the enclosing definition
  --    has an explicit type signature, GHC will solve the 'HasCallStack'
  --    constraint for the singleton 'CallStack' containing just the
  --    current call-site.
  --
  -- 'CallStack's do not interact with the RTS and do not require compilation
  -- with @-prof@. On the other hand, as they are built up explicitly via the
  -- 'HasCallStack' constraints, they will generally not contain as much
  -- information as the simulated call-stacks maintained by the RTS.
  --
  -- A 'CallStack' is a @[(String, SrcLoc)]@. The @String@ is the name of
  -- function that was called, the 'SrcLoc' is the call-site. The list is
  -- ordered with the most recently called function at the head.
  --
  -- NOTE: The intrepid user may notice that 'HasCallStack' is just an
  -- alias for an implicit parameter @?callStack :: CallStack@. This is an
  -- implementation detail and __should not__ be considered part of the
  -- 'CallStack' API, we may decide to change the implementation in the
  -- future.
  --
  -- @since 4.8.1.0
  data CallStack
    = EmptyCallStack
    | PushCallStack [Char] SrcLoc CallStack
    | FreezeCallStack CallStack
      -- ^ Freeze the stack at the given @CallStack@, preventing any further
      -- call-sites from being pushed onto it.
  
    -- See Note [Overview of implicit CallStacks]
  
  -- | Extract a list of call-sites from the 'CallStack'.
  --
  -- The list is ordered by most recent call.
  --
  -- @since 4.8.1.0
  getCallStack :: CallStack -> [([Char], SrcLoc)]
  getCallStack stk = case stk of
    EmptyCallStack            -> []
    PushCallStack fn loc stk' -> (fn,loc) : getCallStack stk'
    FreezeCallStack stk'      -> getCallStack stk'
  
  -- | Convert a list of call-sites to a 'CallStack'.
  --
  -- @since 4.9.0.0
  fromCallSiteList :: [([Char], SrcLoc)] -> CallStack
  fromCallSiteList ((fn,loc):cs) = PushCallStack fn loc (fromCallSiteList cs)
  fromCallSiteList []            = EmptyCallStack
  
  -- Note [Definition of CallStack]
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  -- CallStack is defined very early in base because it is
  -- used by error and undefined. At this point in the dependency graph,
  -- we do not have enough functionality to (conveniently) write a nice
  -- pretty-printer for CallStack. The sensible place to define the
  -- pretty-printer would be GHC.Stack, which is the main access point,
  -- but unfortunately GHC.Stack imports GHC.Exception, which *needs*
  -- the pretty-printer. So the CallStack type and functions are split
  -- between three modules:
  --
  -- 1. GHC.Stack.Types: defines the type and *simple* functions
  -- 2. GHC.Exception: defines the pretty-printer
  -- 3. GHC.Stack: exports everything and acts as the main access point
  
  
  -- | Push a call-site onto the stack.
  --
  -- This function has no effect on a frozen 'CallStack'.
  --
  -- @since 4.9.0.0
  pushCallStack :: ([Char], SrcLoc) -> CallStack -> CallStack
  pushCallStack (fn, loc) stk = case stk of
    FreezeCallStack _ -> stk
    _                 -> PushCallStack fn loc stk
  {-# INLINE pushCallStack #-}
  
  
  -- | The empty 'CallStack'.
  --
  -- @since 4.9.0.0
  emptyCallStack :: CallStack
  emptyCallStack = EmptyCallStack
  {-# INLINE emptyCallStack #-}
  
  
  -- | Freeze a call-stack, preventing any further call-sites from being appended.
  --
  -- prop> pushCallStack callSite (freezeCallStack callStack) = freezeCallStack callStack
  --
  -- @since 4.9.0.0
  freezeCallStack :: CallStack -> CallStack
  freezeCallStack stk = FreezeCallStack stk
  {-# INLINE freezeCallStack #-}
  
  
  -- | A single location in the source code.
  --
  -- @since 4.8.1.0
  data SrcLoc = SrcLoc
    { srcLocPackage   :: [Char]
    , srcLocModule    :: [Char]
    , srcLocFile      :: [Char]
    , srcLocStartLine :: Int
    , srcLocStartCol  :: Int
    , srcLocEndLine   :: Int
    , srcLocEndCol    :: Int
    } deriving Eq
  