Movatterモバイル変換
[0]ホーム
{-# LANGUAGE NoImplicitPrelude #-}{-# LANGUAGE ConstraintKinds #-}{-# LANGUAGE ImplicitParams #-}{-# LANGUAGE KindSignatures #-}{-# LANGUAGE PolyKinds #-}{-# LANGUAGE RankNTypes #-}{-# LANGUAGE Trustworthy #-}{-# OPTIONS_HADDOCK not-home #-}-- 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.-------------------------------------------------------------------------------moduleGHC.Stack.Types(-- * Implicit call stacksCallStack(..),HasCallStack,emptyCallStack,freezeCallStack,fromCallSiteList,getCallStack,pushCallStack,-- * Source locationsSrcLoc(..))where{-Ideally these would live in GHC.Stack but sadly they can't due to thisimport 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)-}importGHC.Classes(Eq)importGHC.Types(Char,Int)-- Make implicit dependency known to build systemimportGHC.Tuple()-- See Note [Depend on GHC.Tuple] in GHC.BaseimportGHC.Integer()-- See Note [Depend on GHC.Integer] in GHC.BaseimportGHC.Natural()-- See Note [Depend on GHC.Natural] in GHC.Base------------------------------------------------------------------------ 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.0typeHasCallStack=(?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.0dataCallStack=EmptyCallStack|PushCallStack[Char]SrcLocCallStack|FreezeCallStackCallStack-- ^ 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.0getCallStack::CallStack->[([Char],SrcLoc)]getCallStack :: CallStack -> [([Char], SrcLoc)]getCallStackCallStackstk=caseCallStackstkofCallStackEmptyCallStack->[]PushCallStack[Char]fnSrcLoclocCallStackstk'->([Char]fn,SrcLocloc)([Char], SrcLoc) -> [([Char], SrcLoc)] -> [([Char], SrcLoc)]forall a. a -> [a] -> [a]:CallStack -> [([Char], SrcLoc)]getCallStackCallStackstk'FreezeCallStackCallStackstk'->CallStack -> [([Char], SrcLoc)]getCallStackCallStackstk'-- | Convert a list of call-sites to a 'CallStack'.---- @since 4.9.0.0fromCallSiteList::[([Char],SrcLoc)]->CallStackfromCallSiteList :: [([Char], SrcLoc)] -> CallStackfromCallSiteList(([Char]fn,SrcLocloc):[([Char], SrcLoc)]cs)=[Char] -> SrcLoc -> CallStack -> CallStackPushCallStack[Char]fnSrcLocloc([([Char], SrcLoc)] -> CallStackfromCallSiteList[([Char], SrcLoc)]cs)fromCallSiteList[]=CallStackEmptyCallStack-- 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.0pushCallStack::([Char],SrcLoc)->CallStack->CallStackpushCallStack :: ([Char], SrcLoc) -> CallStack -> CallStackpushCallStack([Char]fn,SrcLocloc)CallStackstk=caseCallStackstkofFreezeCallStackCallStack_->CallStackstkCallStack_->[Char] -> SrcLoc -> CallStack -> CallStackPushCallStack[Char]fnSrcLoclocCallStackstk{-# INLINEpushCallStack#-}-- | The empty 'CallStack'.---- @since 4.9.0.0emptyCallStack::CallStackemptyCallStack :: CallStackemptyCallStack=CallStackEmptyCallStack{-# INLINEemptyCallStack#-}-- | Freeze a call-stack, preventing any further call-sites from being appended.---- prop> pushCallStack callSite (freezeCallStack callStack) = freezeCallStack callStack---- @since 4.9.0.0freezeCallStack::CallStack->CallStackfreezeCallStack :: CallStack -> CallStackfreezeCallStackCallStackstk=CallStack -> CallStackFreezeCallStackCallStackstk{-# INLINEfreezeCallStack#-}-- | A single location in the source code.---- @since 4.8.1.0dataSrcLoc=SrcLoc{SrcLoc -> [Char]srcLocPackage::[Char],SrcLoc -> [Char]srcLocModule::[Char],SrcLoc -> [Char]srcLocFile::[Char],SrcLoc -> IntsrcLocStartLine::Int,SrcLoc -> IntsrcLocStartCol::Int,SrcLoc -> IntsrcLocEndLine::Int,SrcLoc -> IntsrcLocEndCol::Int}derivingEq-- ^ @since 4.9.0.0
[8]ページ先頭