Commit 235fd88a authored by Austin Seipp's avatar Austin Seipp

Turn -XTypeHoles into a (on by default) warning

After some discussion on ghc-devs@ and elsewhere, it seemed favorable to
make this change as type holes don't let any invalid programs though,
they merely change what the compiler reports in case of certain errors
(namely unbound occurrences, or _ appearing on a LHS.)

Now, the warning mechanism is controlled by -f[no-]warn-type-errors,
just like any other regular warning. Again, on by default.

The documentation and tests have been updated accordingly.
Signed-off-by: default avatarAustin Seipp <austin@well-typed.com>
parent 3e633d9b
......@@ -464,6 +464,7 @@ data WarningFlag =
| Opt_WarnUnsupportedCallingConventions
| Opt_WarnUnsupportedLlvmVersion
| Opt_WarnInlineRuleShadowing
| Opt_WarnTypeHoles
deriving (Eq, Show, Enum)
data Language = Haskell98 | Haskell2010
......@@ -577,7 +578,6 @@ data ExtensionFlag
| Opt_TraditionalRecordSyntax
| Opt_LambdaCase
| Opt_MultiWayIf
| Opt_TypeHoles
| Opt_NegativeLiterals
| Opt_EmptyCase
deriving (Eq, Enum, Show)
......@@ -2575,6 +2575,7 @@ fWarningFlags = [
( "warn-identities", Opt_WarnIdentities, nop ),
( "warn-auto-orphans", Opt_WarnAutoOrphans, nop ),
( "warn-tabs", Opt_WarnTabs, nop ),
( "warn-type-holes", Opt_WarnTypeHoles, nop ),
( "warn-unrecognised-pragmas", Opt_WarnUnrecognisedPragmas, nop ),
( "warn-lazy-unlifted-bindings", Opt_WarnLazyUnliftedBindings,
\_ -> deprecate "it has no effect, and will be removed in GHC 7.10" ),
......@@ -2849,7 +2850,6 @@ xFlags = [
( "UndecidableInstances", Opt_UndecidableInstances, nop ),
( "IncoherentInstances", Opt_IncoherentInstances, nop ),
( "PackageImports", Opt_PackageImports, nop ),
( "TypeHoles", Opt_TypeHoles, nop ),
( "NegativeLiterals", Opt_NegativeLiterals, nop ),
( "EmptyCase", Opt_EmptyCase, nop )
]
......@@ -2990,6 +2990,7 @@ standardWarnings
Opt_WarnWarningsDeprecations,
Opt_WarnDeprecatedFlags,
Opt_WarnAMP,
Opt_WarnTypeHoles,
Opt_WarnUnrecognisedPragmas,
Opt_WarnPointlessPragmas,
Opt_WarnDuplicateConstraints,
......
......@@ -104,7 +104,7 @@ finishHsVar name
rnExpr (HsVar v)
= do { mb_name <- lookupOccRn_maybe v
; case mb_name of {
Nothing -> do { opt_TypeHoles <- xoptM Opt_TypeHoles
Nothing -> do { opt_TypeHoles <- woptM Opt_WarnTypeHoles
; if opt_TypeHoles && startsWithUnderscore (rdrNameOcc v)
then return (HsUnboundVar v, emptyFVs)
else do { n <- reportUnboundName v; finishHsVar n } } ;
......@@ -313,7 +313,7 @@ Since all the symbols are reservedops we can simply reject them.
We return a (bogus) EWildPat in each case.
\begin{code}
rnExpr e@EWildPat = do { holes <- xoptM Opt_TypeHoles
rnExpr e@EWildPat = do { holes <- woptM Opt_WarnTypeHoles
; if holes
then return (hsHoleExpr, emptyFVs)
else patSynErr e
......
......@@ -18,13 +18,14 @@
<itemizedlist>
<listitem>
<para>
GHC now supports "type holes" with the
<literal>TypeHoles</literal> extension. When enabled, the
unbound literal <literal>_</literal> may be used during
development in place of a regular identifier, and GHC will
respond with the type necessary to "fill in the hole."
TODO FIXME: reference.
By default, GHC has a new warning enabled,
<literal>-fwarn-type-holes</literal>, which causes the
compiler to respond with the types of unbound
variables it encounters in the source code. (It is
reminiscient of the "holes" feature in languages such
as Agda.)
For more information, see <xref linkend="type-holes"/>.
</para>
</listitem>
......
......@@ -1224,12 +1224,6 @@
<entry>dynamic</entry>
<entry><option>-</option></entry>
</row>
<row>
<entry><option>-XTypeHoles</option></entry>
<entry>Enable <link linkend="type-holes">holes</link> in expressions.</entry>
<entry>dynamic</entry>
<entry><option>--XNoTypeHoles</option></entry>
</row>
<row>
<entry><option>-fpackage-trust</option></entry>
<entry>Enable <link linkend="safe-haskell">Safe Haskell</link> trusted package requirement for trustworthy modules.</entry>
......@@ -1527,6 +1521,13 @@
<entry><option>-fno-warn-amp</option></entry>
</row>
<row>
<entry><option>-fwarn-type-holes</option></entry>
<entry>Enable <link linkend="type-holes">holes</link> in expressions.</entry>
<entry>dynamic</entry>
<entry><option>-fno-warn-type-holes</option></entry>
</row>
</tbody>
</tgroup>
</informaltable>
......
......@@ -7668,11 +7668,14 @@ with <option>-XNoMonoLocalBinds</option> but type inference becomes less predica
</sect3>
</sect2>
<sect2 id="type-holes">
</sect1>
<!-- ==================== End of type system extensions ================= -->
<sect1 id="type-holes">
<title>Type Holes</title>
<para>Type hole support is enabled with the option
<option>-XTypeHoles</option>.</para>
<option>-fwarn-type-holes</option>, which is enabled by default.</para>
<para>
The goal of the type holes extension is not to change the type system, but to help with writing Haskell
......@@ -7772,11 +7775,9 @@ Failed, modules loaded: none.
This ensures that an unbound identifier is never reported with a too polymorphic type, like
<literal>forall a. a</literal>, when used multiple times for types that can not be unified.
</para>
</sect2>
</sect1>
<!-- ==================== End of type system extensions ================= -->
<!-- ==================== Deferring type errors ================= -->
<sect1 id="defer-type-errors">
<title>Deferring type errors to runtime</title>
......
......@@ -1093,6 +1093,26 @@ test.hs:(5,4)-(6,7):
<variablelist>
<varlistentry>
<term><option>-fwarn-type-holes</option>:</term>
<listitem>
<indexterm><primary><option>-fwarn-type-holes</option></primary>
</indexterm>
<indexterm><primary>warnings</primary></indexterm>
<para>When the compiler encounters an unbound local
variable prefixed with <literal>_</literal>, or encounters
the literal <literal>_</literal> on the right-hand side of
an expression, the error message for the unbound term
includes the type it needs to type check. It works
particularly well with <link
linkend="defer-type-errors">deferred type errors</link>.
See <xref linkend="type-holes"/></para>
<para>This warning is on by default.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-fdefer-type-errors</option>:</term>
<listitem>
......
......@@ -33,7 +33,6 @@ expectedGhcOnlyExtensions :: [String]
expectedGhcOnlyExtensions = ["RelaxedLayout",
"AlternativeLayoutRule",
"AlternativeLayoutRuleTransitional",
"TypeHoles",
"JavaScriptFFI"]
expectedCabalOnlyExtensions :: [String]
......
{-# OPTIONS_GHC -fno-warn-type-holes #-}
-- !!! Illegal _ in expression
module M where
f x = x _ 1
mod71.hs:3:9: Pattern syntax in expression context: _
mod71.hs:4:9: Pattern syntax in expression context: _
{-# OPTIONS_GHC -fno-warn-type-holes #-}
module ShouldFail where
-- !!! Pattern syntax in expressions
......
rnfail016.hs:5:7: Pattern syntax in expression context: x@x
rnfail016.hs:6:7: Pattern syntax in expression context: x@x
rnfail016.hs:6:7: Pattern syntax in expression context: ~x
rnfail016.hs:7:7: Pattern syntax in expression context: ~x
rnfail016.hs:7:7: Pattern syntax in expression context: _
rnfail016.hs:8:7: Pattern syntax in expression context: _
{-# LANGUAGE TypeHoles #-}
module Holes where
f = _
......
holes.hs:5:5: Warning:
holes.hs:3:5: Warning:
Found hole ‛_’ with type: t
Where: ‛t’ is a rigid type variable bound by
the inferred type of f :: t at holes.hs:5:1
Relevant bindings include f :: t (bound at holes.hs:5:1)
the inferred type of f :: t at holes.hs:3:1
Relevant bindings include f :: t (bound at holes.hs:3:1)
In the expression: _
In an equation for ‛f’: f = _
holes.hs:8:7: Warning:
holes.hs:6:7: Warning:
Found hole ‛_’ with type: Char
Relevant bindings include
x :: Int (bound at holes.hs:8:3)
g :: Int -> Char (bound at holes.hs:8:1)
x :: Int (bound at holes.hs:6:3)
g :: Int -> Char (bound at holes.hs:6:1)
In the expression: _
In an equation for ‛g’: g x = _
holes.hs:10:5: Warning:
holes.hs:8:5: Warning:
Found hole ‛_’ with type: [Char]
Relevant bindings include h :: [Char] (bound at holes.hs:10:1)
Relevant bindings include h :: [Char] (bound at holes.hs:8:1)
In the first argument of ‛(++)’, namely ‛_’
In the expression: _ ++ "a"
In an equation for ‛h’: h = _ ++ "a"
holes.hs:13:15: Warning:
holes.hs:11:15: Warning:
Found hole ‛_’ with type: b0
Where: ‛b0’ is an ambiguous type variable
Relevant bindings include
y :: [a] (bound at holes.hs:13:3)
z :: [a] -> [a] (bound at holes.hs:13:1)
y :: [a] (bound at holes.hs:11:3)
z :: [a] -> [a] (bound at holes.hs:11:1)
In the second argument of ‛const’, namely ‛_’
In the expression: const y _
In an equation for ‛z’: z y = const y _
{-# LANGUAGE TypeHoles #-}
module Holes2 where
f = show _
holes2.hs:5:5: Warning:
holes2.hs:3:5: Warning:
No instance for (Show a0) arising from a use of ‛show’
The type variable ‛a0’ is ambiguous
Note: there are several potential instances:
......@@ -11,10 +11,10 @@ holes2.hs:5:5: Warning:
In the expression: show _
In an equation for ‛f’: f = show _
holes2.hs:5:10: Warning:
holes2.hs:3:10: Warning:
Found hole ‛_’ with type: a0
Where: ‛a0’ is an ambiguous type variable
Relevant bindings include f :: String (bound at holes2.hs:5:1)
Relevant bindings include f :: String (bound at holes2.hs:3:1)
In the first argument of ‛show’, namely ‛_’
In the expression: show _
In an equation for ‛f’: f = show _
{-# LANGUAGE TypeHoles #-}
module Holes3 where
f = _
......
holes3.hs:5:5:
holes3.hs:3:5:
Found hole ‛_’ with type: t
Where: ‛t’ is a rigid type variable bound by
the inferred type of f :: t at holes3.hs:5:1
Relevant bindings include f :: t (bound at holes3.hs:5:1)
the inferred type of f :: t at holes3.hs:3:1
Relevant bindings include f :: t (bound at holes3.hs:3:1)
In the expression: _
In an equation for ‛f’: f = _
holes3.hs:8:7:
holes3.hs:6:7:
Found hole ‛_gr’ with type: Char
Relevant bindings include
x :: Int (bound at holes3.hs:8:3)
g :: Int -> Char (bound at holes3.hs:8:1)
x :: Int (bound at holes3.hs:6:3)
g :: Int -> Char (bound at holes3.hs:6:1)
In the expression: _gr
In an equation for ‛g’: g x = _gr
holes3.hs:10:5:
holes3.hs:8:5:
Found hole ‛_aa’ with type: [Char]
Relevant bindings include h :: [Char] (bound at holes3.hs:10:1)
Relevant bindings include h :: [Char] (bound at holes3.hs:8:1)
In the first argument of ‛(++)’, namely ‛_aa’
In the expression: _aa ++ "a"
In an equation for ‛h’: h = _aa ++ "a"
holes3.hs:13:15:
holes3.hs:11:15:
Found hole ‛_x’ with type: b0
Where: ‛b0’ is an ambiguous type variable
Relevant bindings include
y :: [a] (bound at holes3.hs:13:3)
z :: [a] -> [a] (bound at holes3.hs:13:1)
y :: [a] (bound at holes3.hs:11:3)
z :: [a] -> [a] (bound at holes3.hs:11:1)
In the second argument of ‛const’, namely ‛_x’
In the expression: const y _x
In an equation for ‛z’: z y = const y _x
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment