summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorEric Seidel <gridaphobe@gmail.com>2015-01-19 16:08:32 -0600
committerAustin Seipp <austin@well-typed.com>2015-01-19 16:08:33 -0600
commitc024af131b9e2538486eb605ba8af6a8d10fe76d (patch)
tree88ab74b92cb05298626bd455624ce822dc390046 /docs
parentc77eecdc35e2fb4664765264a72ed3f29e50c047 (diff)
downloadhaskell-c024af131b9e2538486eb605ba8af6a8d10fe76d.tar.gz
Expose source locations via Implicit Parameters of type GHC.Location.Location
Summary: IPs with this type will always be solved for the current source location. If another IP of the same type is in scope, the two locations will be appended, creating a call-stack. The Location type is kept abstract so users cannot create them, but a Location can be turned into a list of SrcLocs, which correspond to individual locations in a program. Each SrcLoc contains a package/module/file name and start/end lines and columns. The only thing missing from the SrcLoc in my opinion is the name of the top-level definition it inhabits. I suspect that would also be useful, but it's not clear to me how to extract the current top-level binder from within the constraint solver. (Surely I'm just missing something here?) I made the (perhaps controversial) decision to have GHC completely ignore the names of Location IPs, meaning that in the following code: bar :: (?myloc :: Location) => String bar = foo foo :: (?loc :: Location) => String foo = show ?loc if I call `bar`, the resulting call-stack will include locations for 1. the use of `?loc` inside `foo`, 2. `foo`s call-site inside `bar`, and 3. `bar`s call-site, wherever that may be. This makes Location IPs very special indeed, and I'm happy to change it if the dissonance is too great. I've also left out any changes to base to make use of Location IPs, since there were some concerns about a snowball effect. I think it would be reasonable to mark this as an experimental feature for now (it is!), and defer using it in base until we have more experience with it. It is, after all, quite easy to define your own version of `error`, `undefined`, etc. that use Location IPs. Test Plan: validate, new test-case is testsuite/tests/typecheck/should_run/IPLocation.hs Reviewers: austin, hvr, simonpj Reviewed By: simonpj Subscribers: simonmar, rodlogic, carter, thomie Differential Revision: https://phabricator.haskell.org/D578 GHC Trac Issues: #9049
Diffstat (limited to 'docs')
-rw-r--r--docs/users_guide/7.12.1-notes.xml43
-rw-r--r--docs/users_guide/glasgow_exts.xml50
2 files changed, 93 insertions, 0 deletions
diff --git a/docs/users_guide/7.12.1-notes.xml b/docs/users_guide/7.12.1-notes.xml
index 0196884591..7f9346edf2 100644
--- a/docs/users_guide/7.12.1-notes.xml
+++ b/docs/users_guide/7.12.1-notes.xml
@@ -34,6 +34,32 @@
TODO FIXME.
</para>
</listitem>
+ <listitem>
+ <para>
+ Implicit parameters of the new base type
+ <literal>GHC.Stack.CallStack</literal> are treated
+ specially, and automatically solved for the current source
+ location. For example
+ <programlisting>
+ f = print (?stk :: CallStack)
+ </programlisting>
+ will print the singleton stack containing the occurrence of
+ <literal>?stk</literal>. If there is another
+ <literal>CallStack</literal> implicit in-scope, the new location
+ will be appended to the existing stack, e.g.
+ <programlisting>
+ f :: (?stk :: CallStack) => IO ()
+ f = print (?stk :: CallStack)
+ </programlisting>
+ will print the occurrence of <literal>?stk</literal> and the
+ call-site of <literal>f</literal>. The name of the implicit
+ parameter does not matter.
+ </para>
+ <para>
+ See the release notes for base for a description of the
+ <literal>CallStack</literal> type.
+ </para>
+ </listitem>
</itemizedlist>
</sect3>
@@ -129,6 +155,23 @@
Version number XXXXX (was 4.7.0.0)
</para>
</listitem>
+ <listitem>
+ <para>
+ A new module <literal>GHC.SrcLoc</literal> was added,
+ exporting a new type <literal>SrcLoc</literal>. A
+ <literal>SrcLoc</literal> contains package, module,
+ and file names, as well as start and end positions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A new type <literal>CallStack</literal> was added for use
+ with the new implicit callstack parameters. A
+ <literal>CallStack</literal> is a
+ <literal>[(String, SrcLoc)]</literal>, sorted by most-recent
+ call.
+ </para>
+ </listitem>
</itemizedlist>
</sect3>
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 684f8f0263..190af38d67 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -7701,6 +7701,56 @@ inner binding of <literal>?x</literal>, so <literal>(f 9)</literal> will return
<literal>14</literal>.
</para>
</sect3>
+
+<sect3><title>Special implicit parameters</title>
+<para>
+GHC treats implicit parameters of type <literal>GHC.Stack.CallStack</literal>
+specially, by resolving them to the current location in the program. Consider:
+<programlisting>
+ f :: String
+ f = show (?loc :: CallStack)
+</programlisting>
+GHC will automatically resolve <literal>?loc</literal> to its source
+location. If another implicit parameter with type <literal>CallStack</literal> is
+in scope, GHC will append the two locations, creating an explicit call-stack. For example:
+<programlisting>
+ f :: (?stk :: CallStack) => String
+ f = show (?stk :: CallStack)
+</programlisting>
+will produce the location of <literal>?stk</literal>, followed by
+<literal>f</literal>'s call-site. Note that the name of the implicit parameter does not
+matter (we used <literal>?loc</literal> above), GHC will solve any implicit parameter
+with the right type. The name does, however, matter when pushing new locations onto
+existing stacks. Consider:
+<programlisting>
+ f :: (?stk :: CallStack) => String
+ f = show (?loc :: CallStack)
+</programlisting>
+When we call <literal>f</literal>, the stack will include the use of <literal>?loc</literal>,
+but not the call to <literal>f</literal>; in this case the names must match.
+</para>
+<para>
+<literal>CallStack</literal> is kept abstract, but
+GHC provides a function
+<programlisting>
+ getCallStack :: CallStack -> [(String, SrcLoc)]
+</programlisting>
+to access the individual call-sites in the stack. The <literal>String</literal>
+is the name of the function that was called, and the <literal>SrcLoc</literal>
+provides the package, module, and file name, as well as the line and column
+numbers. The stack will never be empty, as the first call-site
+will be the location at which the implicit parameter was used. GHC will also
+never infer <literal>?loc :: CallStack</literal> as a type constraint, which
+means that functions must explicitly ask to be told about their call-sites.
+</para>
+<para>
+A potential "gotcha" when using implicit <literal>CallStack</literal>s is that
+the <literal>:type</literal> command in GHCi will not report the
+<literal>?loc :: CallStack</literal> constraint, as the typechecker will
+immediately solve it. Use <literal>:info</literal> instead to print the
+unsolved type.
+</para>
+</sect3>
</sect2>
<sect2 id="kinding">