summaryrefslogtreecommitdiff
path: root/docs/users_guide/glasgow_exts.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/users_guide/glasgow_exts.rst')
-rw-r--r--docs/users_guide/glasgow_exts.rst186
1 files changed, 109 insertions, 77 deletions
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index 6ea2ef65df..c09d0efe6d 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -8040,83 +8040,6 @@ a type signature for ``y``, then ``y`` will get type
``let`` will see the inner binding of ``?x``, so ``(f 9)`` will return
``14``.
-.. _implicit-callstacks:
-
-Implicit CallStacks
-~~~~~~~~~~~~~~~~~~~
-
-Implicit parameters of the new ``base`` type ``GHC.Stack.CallStack`` are
-treated specially in function calls, the solver automatically pushes
-the source location of the call onto the ``CallStack`` in the
-environment. For example
-
-::
-
- myerror :: (?callStack :: CallStack) => String -> a
- myerror msg = error (msg ++ "\n" ++ prettyCallStack ?callStack)
-
- ghci> myerror "die"
- *** Exception: die
- CallStack (from ImplicitParams):
- myerror, called at <interactive>:2:1 in interactive:Ghci1
-
-prints the call-site of ``myerror``. The name of the implicit
-parameter does not matter, but within ``base`` we call it
-``?callStack``.
-
-The ``CallStack`` will only extend as far as the types allow it, for
-example
-
-.. code-block:: none
-
- head :: (?callStack :: CallStack) => [a] -> a
- head [] = myerror "empty"
- head (x:xs) = x
-
- bad :: Int
- bad = head []
-
- ghci> bad
- *** Exception: empty
- CallStack (from ImplicitParams):
- myerror, called at Bad.hs:8:15 in main:Bad
- head, called at Bad.hs:12:7 in main:Bad
-
-includes the call-site of ``myerror`` in ``head``, and of ``head`` in
-``bad``, but not the call-site of ``bad`` at the GHCi prompt.
-
-GHC will never report an unbound implicit ``CallStack``, and will
-instead default such occurrences to the empty ``CallStack``.
-
-``CallStack`` is kept abstract, but GHC provides a function ::
-
- getCallStack :: CallStack -> [(String, SrcLoc)]
-
-to access the individual call-sites in the stack. The ``String`` is the
-name of the function that was called, and the ``SrcLoc`` provides the
-package, module, and file name, as well as the line and column numbers.
-GHC will infer ``CallStack`` constraints using the same rules as for
-ordinary implicit parameters.
-
-``GHC.Stack`` additionally exports a function ``freezeCallStack`` that
-allows users to freeze a ``CallStack``, preventing any future push
-operations from having an effect. This can be used by library authors
-to prevent ``CallStack``\s from exposing unnecessary implementation
-details. Consider the ``head`` example above, the ``myerror`` line in
-the printed stack is not particularly enlightening, so we might choose
-to suppress it by freezing the ``CallStack`` that we pass to ``myerror``.
-
-.. code-block:: none
-
- head :: (?callStack :: CallStack) => [a] -> a
- head [] = let ?callStack = freezeCallStack ?callStack in myerror "empty"
- head (x:xs) = x
-
- ghci> head []]
- *** Exception: empty
- CallStack (from ImplicitParams):
- head, called at Bad.hs:12:7 in main:Bad
-
.. _kinding:
@@ -12879,3 +12802,112 @@ intuitive: ::
let f = /\a \(d::Eq a). fst (member, True) in body
Note that the bang has no effect at all in this case
+
+.. _hascallstack:
+
+HasCallStack
+============
+
+``GHC.Stack.HasCallStack`` is 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 ::
+
+ errorWithCallStack :: HasCallStack => String -> a
+
+as a variant of ``error`` that will get its call-site. We can access the
+call-stack inside ``errorWithCallStack`` with ``GHC.Stack.callStack``. ::
+
+ errorWithCallStack :: HasCallStack => String -> a
+ errorWithCallStack msg = error (msg ++ "\n" ++ prettyCallStack callStack)
+
+Thus, if we call ``errorWithCallStack`` we will get a formatted call-stack
+alongside our error message.
+
+.. code-block:: none
+
+ ghci> errorWithCallStack "die"
+ *** Exception: die
+ CallStack (from HasCallStack):
+ errorWithCallStack, called at <interactive>:2:1 in interactive:Ghci1
+
+The ``CallStack`` will only extend as far as the types allow it, for
+example ::
+
+ head :: HasCallStack => [a] -> a
+ head [] = errorWithCallStack "empty"
+ head (x:xs) = x
+
+ bad :: Int
+ bad = head []
+
+.. code-block:: none
+
+ ghci> bad
+ *** Exception: empty
+ CallStack (from HasCallStack):
+ errorWithCallStack, called at Bad.hs:8:15 in main:Bad
+ head, called at Bad.hs:12:7 in main:Bad
+
+includes the call-site of ``errorWithCallStack`` in ``head``,
+and of ``head`` in ``bad``,
+but not the call-site of ``bad`` at the GHCi prompt.
+
+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 push the new call-site
+ onto 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`` is kept abstract, but GHC provides a function ::
+
+ getCallStack :: CallStack -> [(String, SrcLoc)]
+
+to access the individual call-sites in the stack. The ``String`` is the
+name of the function that was called, and the ``SrcLoc`` provides the
+package, module, and file name, as well as the line and column numbers.
+
+``GHC.Stack`` additionally exports a function ``withFrozenCallStack`` that
+allows users to freeze the current ``CallStack``, preventing any future push
+operations from having an effect. This can be used by library authors
+to prevent ``CallStack``\s from exposing unnecessary implementation
+details. Consider the ``head`` example above, the ``errorWithCallStack`` line in
+the printed stack is not particularly enlightening, so we might choose
+to suppress it by freezing the ``CallStack`` that we pass to ``errorWithCallStack``. ::
+
+ head :: HasCallStack => [a] -> a
+ head [] = withFrozenCallStack (errorWithCallStack "empty")
+ head (x:xs) = x
+
+.. code-block:: none
+
+ ghci> head []
+ *** Exception: empty
+ CallStack (from HasCallStack):
+ head, called at Bad.hs:12:7 in main:Bad
+
+**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.
+
+Compared with other sources of stack traces
+-------------------------------------------
+
+``HasCallStack`` does not interact with the RTS and does not require
+compilation with ``-prof``. On the other hand, as the ``CallStack`` is
+built up explicitly via the ``HasCallStack`` constraints, it will
+generally not contain as much information as the simulated call-stacks
+maintained by the RTS.