diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2015-06-24 23:27:59 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2015-06-26 08:33:10 +0100 |
commit | fb7b6922573af76a954d939c85e6af7c39a19896 (patch) | |
tree | b0604fd3ca0d94d74758c5767e048f9027fe8754 /docs/users_guide/glasgow_exts.xml | |
parent | 95fc6d5940582c8a42cd8f65b7e21b6e6370ea83 (diff) | |
download | haskell-fb7b6922573af76a954d939c85e6af7c39a19896.tar.gz |
Treat out-of-scope variables as holes
This patch implements the idea in Trac #10569.
* An out-of-scope variable is treated as a typed expression
hole.
* That is, we don't report it in the type checker, not the
renamer, and we when we do report it, we give its type.
* Moreover, we can defer the error to runtime with
-fdefer-typed-holes
In implementation terms:
* The renamer turns an unbound variable into a HsUnboundVar
* The type checker emits a Hole constraint for a
HsUnboundVar, and turns it back into a HsVar
It was a bit painful to implement because a whole raft of
error messages change slightly. But there was absolutely
nothing hard in principle.
Holes are reported with a bunch of possibly-useful context,
notably the "relevant bindings". I found that this was
distracting clutter in the very common case of a mis-typed
variable that is only accidentally not in scope, so I've
arranged to print the context information only for true holes,
that is ones starting with an underscore.
Unbound data constructors use in patterns, like
f (D x) = x
are still reportd by the renamer, and abort compilation
before type checking.
Diffstat (limited to 'docs/users_guide/glasgow_exts.xml')
-rw-r--r-- | docs/users_guide/glasgow_exts.xml | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 44caf76295..462509290a 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -8779,15 +8779,39 @@ be suppressed entirely by <option>-fnowarn-typed-holes</option>). <para> The result is that a hole will behave like <literal>undefined</literal>, but with the added benefits that it shows a -warning at compile time and will show another warning message if it gets -evaluated at runtime.. This behaviour follows that of the +warning at compile time, and will show the same message if it gets +evaluated at runtime. This behaviour follows that of the <literal>-fdefer-type-errors</literal> option, which implies <literal>-fdefer-typed-holes</literal>. See <xref linkend="defer-type-errors"/>. </para> </listitem> <listitem><para> -Unbound identifiers with the same name are never unified, even within the +All unbound identifiers are treated as typed holes, <emphasis>whether or not they +start with an underscore</emphasis>. The only difference is in the error message: +<programlisting> +cons z = z : True : _x : y +</programlisting> +yields the errors +<programlisting> +Foo.hs:5:15: error: + Found hole: _x :: Bool + Relevant bindings include + p :: Bool (bound at Foo.hs:3:6) + cons :: Bool -> [Bool] (bound at Foo.hs:3:1) + +Foo.hs:5:20: error: + Variable not in scope: y :: [Bool] +</programlisting> +More information is given for explicit holes (i.e. ones that start with an underscore), +than for out-of-scope variables, because the latter are often +unintended typos, so the extra information is distracting. +If you the detailed information, use a leading underscore to +make explicit your intent to use a hole. +</para></listitem> + +<listitem><para> +Unbound identifiers with the same name are never unified, even within the same function, but shown individually. For example: <programlisting> @@ -8824,9 +8848,18 @@ is a perfectly legal variable, and its behaviour is unchanged when it is in scop <programlisting> f _x = _x + 1 </programlisting> -does not elict any errors. Only a variable starting with an underscore <emphasis>that is not in scope</emphasis> -is treated as an error (which it always was), albeit now with a more informative error message +does not elict any errors. Only a variable <emphasis>that is not in scope</emphasis> +(whether or not it starts with an underscore) +is treated as an error (which it always was), albeit now with a more informative error message. +</para></listitem> + +<listitem><para> +Unbound data constructors used in expressions behave exactly as above. +However, unbound data constructors used in <emphasis>patterns</emphasis> cannot +be deferred, and instead bring compilation to a halt. (In implementation terms, they +are reported by the renamer rather than the type checker.) </para></listitem> + </itemizedlist> </para> |