Turn -XTypeHoles into a (on by default) warning
authorAustin Seipp <austin@well-typed.com>
Wed, 15 Jan 2014 02:16:26 +0000 (20:16 -0600)
committerAustin Seipp <austin@well-typed.com>
Wed, 15 Jan 2014 02:16:26 +0000 (20:16 -0600)
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: Austin Seipp <austin@well-typed.com>
17 files changed:
compiler/main/DynFlags.hs
compiler/rename/RnExpr.lhs
docs/users_guide/7.8.1-notes.xml
docs/users_guide/flags.xml
docs/users_guide/glasgow_exts.xml
docs/users_guide/using.xml
testsuite/tests/driver/T4437.hs
testsuite/tests/module/mod71.hs
testsuite/tests/module/mod71.stderr
testsuite/tests/rename/should_fail/rnfail016.hs
testsuite/tests/rename/should_fail/rnfail016.stderr
testsuite/tests/typecheck/should_compile/holes.hs
testsuite/tests/typecheck/should_compile/holes.stderr
testsuite/tests/typecheck/should_compile/holes2.hs
testsuite/tests/typecheck/should_compile/holes2.stderr
testsuite/tests/typecheck/should_compile/holes3.hs
testsuite/tests/typecheck/should_compile/holes3.stderr

index 20b61c1..29f3834 100644 (file)
@@ -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,
index 3b63618..0da22d6 100644 (file)
@@ -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
index 46624ff..a5edeea 100644 (file)
     <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>
 
index 2422b9d..a9b989d 100644 (file)
             <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>
             <entry>dynamic</entry>
             <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>
index 70a3876..32f2c2e 100644 (file)
@@ -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>
index 0d5881f..7192e6a 100644 (file)
@@ -1094,6 +1094,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>
           <indexterm><primary><option>-fdefer-type-errors</option></primary>
index 694bd5f..e816f8a 100644 (file)
@@ -33,7 +33,6 @@ expectedGhcOnlyExtensions :: [String]
 expectedGhcOnlyExtensions = ["RelaxedLayout",
                              "AlternativeLayoutRule",
                              "AlternativeLayoutRuleTransitional",
-                             "TypeHoles",
                              "JavaScriptFFI"]
 
 expectedCabalOnlyExtensions :: [String]
index 49cc66d..7798cfc 100644 (file)
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -fno-warn-type-holes #-}
 -- !!! Illegal _ in expression
 module M where
 f x = x _ 1
index 956f05e..f42d17d 100644 (file)
@@ -1,2 +1,2 @@
 
-mod71.hs:3:9: Pattern syntax in expression context: _
+mod71.hs:4:9: Pattern syntax in expression context: _
index 1fa71c5..5e71207 100644 (file)
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -fno-warn-type-holes #-}
 module ShouldFail where
 
 -- !!! Pattern syntax in expressions
index ed9debd..b24db3c 100644 (file)
@@ -1,6 +1,6 @@
 
-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: _
index 953982e..2985863 100644 (file)
@@ -1,33 +1,33 @@
 
-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 _
index c034c87..d75b5f3 100644 (file)
@@ -1,5 +1,5 @@
 
-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 _
index c4666ec..abfeab0 100644 (file)
@@ -1,33 +1,33 @@
 
-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