summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerijn Verstraaten <merijn@inconsistent.nl>2014-11-21 15:32:38 -0600
committerAustin Seipp <austin@well-typed.com>2014-11-21 17:04:57 -0600
commit2cc854b7133e38c7ad1107057931761782d03594 (patch)
tree399b3ccdcc7c43dce2e598d1ea42e72ff818000c
parent624a7c5a2eee0c0ba486a45550680052c2c79849 (diff)
downloadhaskell-2cc854b7133e38c7ad1107057931761782d03594.tar.gz
Add -fdefer-typed-holes flag which defers hole errors to runtime.
Summary: As proposed by Richard on Trac. This patch adds a new flag -fdefer-typed-holes and changes the semantics of the -fno-warn-typed-holes flag. To summarise, by default GHC has typed holes enabled and produces a compile error when it encounters a typed hole. When -fdefer-type-errors OR -fdefer-typed-holes is enabled, hole errors are converted to warnings and result in runtime errors when evaluated. The warning flag -fwarn-typed-holes is on by default. Without -fdefer-type-errors or -fdefer-typed-holes this flag is a no-op, since typed holes are an error under these conditions. If either of the defer flags are enabled (converting typed hole errors into warnings) the -fno-warn-typed-holes flag disables the warnings. This means compilation silently succeeds and evaluating a hole will produce a runtime error. The rationale behind allowing typed holes warnings to be silenced is that tools like Syntastic for vim highlight warnings and hole warnings may be undesirable. Signed-off-by: Merijn Verstraaten <merijn@inconsistent.nl> Test Plan: validate Reviewers: austin, simonpj, thomie Reviewed By: simonpj, thomie Subscribers: Fuuzetsu, thomie, carter Differential Revision: https://phabricator.haskell.org/D442 GHC Trac Issues: #9497 Conflicts: compiler/main/DynFlags.hs
-rw-r--r--compiler/main/DynFlags.hs22
-rw-r--r--compiler/rename/RnExpr.lhs9
-rw-r--r--compiler/typecheck/TcDeriv.lhs2
-rw-r--r--compiler/typecheck/TcErrors.lhs74
-rw-r--r--compiler/typecheck/TcRnDriver.lhs2
-rw-r--r--docs/users_guide/flags.xml25
-rw-r--r--docs/users_guide/glasgow_exts.xml53
-rw-r--r--docs/users_guide/using.xml34
-rw-r--r--testsuite/tests/module/mod71.stderr11
-rw-r--r--testsuite/tests/rename/should_fail/rnfail016.stderr2
-rw-r--r--testsuite/tests/typecheck/should_compile/T9497a.hs2
-rw-r--r--testsuite/tests/typecheck/should_compile/T9497a.stderr6
-rw-r--r--testsuite/tests/typecheck/should_compile/T9497b.hs2
-rw-r--r--testsuite/tests/typecheck/should_compile/T9497b.stderr0
-rw-r--r--testsuite/tests/typecheck/should_compile/T9497c.hs2
-rw-r--r--testsuite/tests/typecheck/should_compile/T9497c.stderr0
-rw-r--r--testsuite/tests/typecheck/should_compile/all.T3
-rw-r--r--testsuite/tests/typecheck/should_fail/T9497d.hs2
-rw-r--r--testsuite/tests/typecheck/should_fail/T9497d.stderr6
-rw-r--r--testsuite/tests/typecheck/should_fail/all.T1
-rw-r--r--testsuite/tests/typecheck/should_run/T9497a-run.hs2
-rw-r--r--testsuite/tests/typecheck/should_run/T9497a-run.stderr7
-rw-r--r--testsuite/tests/typecheck/should_run/T9497b-run.hs2
-rw-r--r--testsuite/tests/typecheck/should_run/T9497b-run.stderr7
-rw-r--r--testsuite/tests/typecheck/should_run/T9497c-run.hs2
-rw-r--r--testsuite/tests/typecheck/should_run/T9497c-run.stderr7
-rwxr-xr-xtestsuite/tests/typecheck/should_run/all.T3
27 files changed, 226 insertions, 62 deletions
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 26662d5cf0..5e3bda9723 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -396,6 +396,7 @@ data GeneralFlag
| Opt_GhciHistory
| Opt_HelpfulErrors
| Opt_DeferTypeErrors
+ | Opt_DeferTypedHoles
| Opt_Parallel
| Opt_GranMacros
| Opt_PIC
@@ -2769,6 +2770,7 @@ fFlags = [
flagSpec ( "cmm-sink", Opt_CmmSink, nop ),
flagSpec ( "cse", Opt_CSE, nop ),
flagSpec ( "defer-type-errors", Opt_DeferTypeErrors, nop ),
+ flagSpec ( "defer-typed-holes", Opt_DeferTypedHoles, nop ),
flagSpec ( "dicts-cheap", Opt_DictsCheap, nop ),
flagSpec ( "dicts-strict", Opt_DictsStrict, nop ),
flagSpec ( "dmd-tx-dict-sel", Opt_DmdTxDictSel, nop ),
@@ -3053,8 +3055,11 @@ default_PIC platform =
(OSDarwin, ArchX86_64) -> [Opt_PIC]
_ -> []
-impliedFlags :: [(ExtensionFlag, TurnOnFlag, ExtensionFlag)]
-impliedFlags
+impliedGFlags :: [(GeneralFlag, TurnOnFlag, GeneralFlag)]
+impliedGFlags = [(Opt_DeferTypeErrors, turnOn, Opt_DeferTypedHoles)]
+
+impliedXFlags :: [(ExtensionFlag, TurnOnFlag, ExtensionFlag)]
+impliedXFlags
-- See Note [Updating flag description in the User's Guide]
= [ (Opt_RankNTypes, turnOn, Opt_ExplicitForAll)
, (Opt_ScopedTypeVariables, turnOn, Opt_ExplicitForAll)
@@ -3399,9 +3404,18 @@ setGeneralFlag f = upd (setGeneralFlag' f)
unSetGeneralFlag f = upd (unSetGeneralFlag' f)
setGeneralFlag' :: GeneralFlag -> DynFlags -> DynFlags
-setGeneralFlag' f dflags = gopt_set dflags f
+setGeneralFlag' f dflags = foldr ($) (gopt_set dflags f) deps
+ where
+ deps = [ if turn_on then setGeneralFlag' d
+ else unSetGeneralFlag' d
+ | (f', turn_on, d) <- impliedGFlags, f' == f ]
+ -- When you set f, set the ones it implies
+ -- NB: use setGeneralFlag recursively, in case the implied flags
+ -- implies further flags
+
unSetGeneralFlag' :: GeneralFlag -> DynFlags -> DynFlags
unSetGeneralFlag' f dflags = gopt_unset dflags f
+ -- When you un-set f, however, we don't un-set the things it implies
--------------------------
setWarningFlag, unSetWarningFlag :: WarningFlag -> DynP ()
@@ -3418,7 +3432,7 @@ setExtensionFlag' f dflags = foldr ($) (xopt_set dflags f) deps
where
deps = [ if turn_on then setExtensionFlag' d
else unSetExtensionFlag' d
- | (f', turn_on, d) <- impliedFlags, f' == f ]
+ | (f', turn_on, d) <- impliedXFlags, f' == f ]
-- When you set f, set the ones it implies
-- NB: use setExtensionFlag recursively, in case the implied flags
-- implies further flags
diff --git a/compiler/rename/RnExpr.lhs b/compiler/rename/RnExpr.lhs
index 30e7112f12..7ef815ff29 100644
--- a/compiler/rename/RnExpr.lhs
+++ b/compiler/rename/RnExpr.lhs
@@ -88,8 +88,7 @@ finishHsVar name
rnExpr (HsVar v)
= do { mb_name <- lookupOccRn_maybe v
; case mb_name of {
- Nothing -> do { opt_TypeHoles <- woptM Opt_WarnTypedHoles
- ; if opt_TypeHoles && startsWithUnderscore (rdrNameOcc v)
+ Nothing -> do { if startsWithUnderscore (rdrNameOcc v)
then return (HsUnboundVar v, emptyFVs)
else do { n <- reportUnboundName v; finishHsVar n } } ;
Just name
@@ -300,11 +299,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 <- woptM Opt_WarnTypedHoles
- ; if holes
- then return (hsHoleExpr, emptyFVs)
- else patSynErr e
- }
+rnExpr EWildPat = return (hsHoleExpr, emptyFVs)
rnExpr e@(EAsPat {}) = patSynErr e
rnExpr e@(EViewPat {}) = patSynErr e
rnExpr e@(ELazyPat {}) = patSynErr e
diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs
index a10945a60b..161bb773e4 100644
--- a/compiler/typecheck/TcDeriv.lhs
+++ b/compiler/typecheck/TcDeriv.lhs
@@ -1881,7 +1881,7 @@ simplifyDeriv pred tvs theta
where p = ctPred ct
-- If we are deferring type errors, simply ignore any insoluble
- -- constraints. Tney'll come up again when we typecheck the
+ -- constraints. They'll come up again when we typecheck the
-- generated instance declaration
; defer <- goptM Opt_DeferTypeErrors
; unless defer (reportAllUnsolved (residual_wanted { wc_flat = bad }))
diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs
index 84a2c16d05..cd5879c7bf 100644
--- a/compiler/typecheck/TcErrors.lhs
+++ b/compiler/typecheck/TcErrors.lhs
@@ -43,6 +43,7 @@ import DynFlags
import StaticFlags ( opt_PprStyle_Debug )
import ListSetOps ( equivClasses )
+import Control.Monad ( when )
import Data.Maybe
import Data.List ( partition, mapAccumL, zip4, nub, sortBy )
\end{code}
@@ -98,22 +99,29 @@ compilation. The errors are turned into warnings in `reportUnsolved`.
reportUnsolved :: WantedConstraints -> TcM (Bag EvBind)
reportUnsolved wanted
= do { binds_var <- newTcEvBinds
- ; defer <- goptM Opt_DeferTypeErrors
- ; report_unsolved (Just binds_var) defer wanted
+ ; defer_errors <- goptM Opt_DeferTypeErrors
+ ; defer_holes <- goptM Opt_DeferTypedHoles
+ ; warn_holes <- woptM Opt_WarnTypedHoles
+ ; report_unsolved (Just binds_var) defer_errors defer_holes
+ warn_holes wanted
; getTcEvBinds binds_var }
reportAllUnsolved :: WantedConstraints -> TcM ()
-- Report all unsolved goals, even if -fdefer-type-errors is on
-- See Note [Deferring coercion errors to runtime]
-reportAllUnsolved wanted = report_unsolved Nothing False wanted
+reportAllUnsolved wanted = do
+ warn_holes <- woptM Opt_WarnTypedHoles
+ report_unsolved Nothing False False warn_holes wanted
report_unsolved :: Maybe EvBindsVar -- cec_binds
- -> Bool -- cec_defer
+ -> Bool -- cec_defer_type_errors
+ -> Bool -- cec_defer_holes
+ -> Bool -- cec_warn_holes
-> WantedConstraints -> TcM ()
-- Important precondition:
-- WantedConstraints are fully zonked and unflattened, that is,
-- zonkWC has already been applied to these constraints.
-report_unsolved mb_binds_var defer wanted
+report_unsolved mb_binds_var defer_errors defer_holes warn_holes wanted
| isEmptyWC wanted
= return ()
| otherwise
@@ -127,7 +135,9 @@ report_unsolved mb_binds_var defer wanted
free_tvs = tyVarsOfWC wanted
err_ctxt = CEC { cec_encl = []
, cec_tidy = tidy_env
- , cec_defer = defer
+ , cec_defer_type_errors = defer_errors
+ , cec_defer_holes = defer_holes
+ , cec_warn_holes = warn_holes
, cec_suppress = False -- See Note [Suppressing error messages]
, cec_binds = mb_binds_var }
@@ -152,8 +162,16 @@ data ReportErrCtxt
-- into warnings, and emit evidence bindings
-- into 'ev' for unsolved constraints
- , cec_defer :: Bool -- True <=> -fdefer-type-errors
- -- Irrelevant if cec_binds = Nothing
+ , cec_defer_type_errors :: Bool -- True <=> -fdefer-type-errors
+ -- Defer type errors until runtime
+ -- Irrelevant if cec_binds = Nothing
+
+ , cec_defer_holes :: Bool -- True <=> -fdefer-typed-holes
+ -- Turn typed holes into runtime errors
+ -- Irrelevant if cec_binds = Nothing
+
+ , cec_warn_holes :: Bool -- True <=> -fwarn-typed-holes
+ -- Controls whether holes produce warnings
, cec_suppress :: Bool -- True <=> More important errors have occurred,
-- so create bindings if need be, but
-- don't issue any more errors/warnings
@@ -231,7 +249,7 @@ reportFlats ctxt flats -- Here 'flats' includes insolble goals
-- Like Int ~ Bool (incl nullary TyCons)
-- or Int ~ t a (AppTy on one side)
("Utterly wrong", utterly_wrong, True, mkGroupReporter mkEqErr)
- , ("Holes", is_hole, True, mkUniReporter mkHoleError)
+ , ("Holes", is_hole, True, mkHoleReporter mkHoleError)
-- Report equalities of form (a~ty). They are usually
-- skolem-equalities, and they cause confusing knock-on
@@ -318,13 +336,13 @@ mkSkolReporter ctxt cts
(EqPred ty1 _, EqPred ty2 _) -> ty1 `cmpType` ty2
_ -> pprPanic "mkSkolReporter" (ppr ct1 $$ ppr ct2)
-mkUniReporter :: (ReportErrCtxt -> Ct -> TcM ErrMsg) -> Reporter
+mkHoleReporter :: (ReportErrCtxt -> Ct -> TcM ErrMsg) -> Reporter
-- Reports errors one at a time
-mkUniReporter mk_err ctxt
+mkHoleReporter mk_err ctxt
= mapM_ $ \ct ->
do { err <- mk_err ctxt ct
- ; maybeReportError ctxt err
- ; maybeAddDeferredBinding ctxt err ct }
+ ; maybeReportHoleError ctxt err
+ ; maybeAddDeferredHoleBinding ctxt err ct }
mkGroupReporter :: (ReportErrCtxt -> [Ct] -> TcM ErrMsg)
-- Make error message for a group
@@ -345,22 +363,30 @@ reportGroup mk_err ctxt cts
-- Add deferred bindings for all
-- But see Note [Always warn with -fdefer-type-errors]
+maybeReportHoleError :: ReportErrCtxt -> ErrMsg -> TcM ()
+maybeReportHoleError ctxt err
+ | cec_defer_holes ctxt
+ = when (cec_warn_holes ctxt)
+ (reportWarning (makeIntoWarning err))
+ | otherwise
+ = reportError err
+
maybeReportError :: ReportErrCtxt -> ErrMsg -> TcM ()
-- Report the error and/or make a deferred binding for it
maybeReportError ctxt err
- | cec_defer ctxt -- See Note [Always warn with -fdefer-type-errors]
+ -- See Note [Always warn with -fdefer-type-errors]
+ | cec_defer_type_errors ctxt
= reportWarning (makeIntoWarning err)
| cec_suppress ctxt
= return ()
| otherwise
= reportError err
-maybeAddDeferredBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM ()
+addDeferredBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM ()
-- See Note [Deferring coercion errors to runtime]
-maybeAddDeferredBinding ctxt err ct
+addDeferredBinding ctxt err ct
| CtWanted { ctev_pred = pred, ctev_evar = ev_id } <- ctEvidence ct
-- Only add deferred bindings for Wanted constraints
- , isHoleCt ct || cec_defer ctxt -- And it's a hole or we have -fdefer-type-errors
, Just ev_binds_var <- cec_binds ctxt -- We have somewhere to put the bindings
= do { dflags <- getDynFlags
; let err_msg = pprLocErrMsg err
@@ -373,6 +399,20 @@ maybeAddDeferredBinding ctxt err ct
| otherwise -- Do not set any evidence for Given/Derived
= return ()
+maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM ()
+maybeAddDeferredHoleBinding ctxt err ct
+ | cec_defer_holes ctxt
+ = addDeferredBinding ctxt err ct
+ | otherwise
+ = return ()
+
+maybeAddDeferredBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM ()
+maybeAddDeferredBinding ctxt err ct
+ | cec_defer_type_errors ctxt
+ = addDeferredBinding ctxt err ct
+ | otherwise
+ = return ()
+
tryReporters :: [ReporterSpec] -> Reporter -> Reporter
-- Use the first reporter in the list whose predicate says True
tryReporters reporters deflt ctxt cts
diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs
index d2e9115d07..2bc64c5cde 100644
--- a/compiler/typecheck/TcRnDriver.lhs
+++ b/compiler/typecheck/TcRnDriver.lhs
@@ -1535,7 +1535,7 @@ runPlans [p] = p
runPlans (p:ps) = tryTcLIE_ (runPlans ps) p
-- | Typecheck (and 'lift') a stmt entered by the user in GHCi into the
--- GHCi 'environemnt'.
+-- GHCi 'environment'.
--
-- By 'lift' and 'environment we mean that the code is changed to
-- execute properly in an IO monad. See Note [Interactively-bound Ids
diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml
index 4aebe5b2c4..56ebcd3f0a 100644
--- a/docs/users_guide/flags.xml
+++ b/docs/users_guide/flags.xml
@@ -1363,12 +1363,29 @@
<row>
<entry><option>-fdefer-type-errors</option></entry>
- <entry>Defer as many type errors as possible until runtime.</entry>
+ <entry>
+ Turn type errors into warnings, <link linkend="defer-type-errors">
+ deferring the error until runtime</link>. Implies
+ <option>-fdefer-typed-holes</option>.
+ </entry>
<entry>dynamic</entry>
<entry><option>-fno-defer-type-errors</option></entry>
</row>
<row>
+ <entry><option>-fdefer-typed-holes</option></entry>
+ <entry>
+ Convert <link linkend="typed-holes">typed hole</link> errors
+ into warnings, <link linkend="defer-type-errors">deferring the
+ error until runtime</link>. Implied by
+ <option>-fdefer-type-errors</option>. See also
+ <option>-fwarn-typed-holes</option>.
+ </entry>
+ <entry>dynamic</entry>
+ <entry><option>-fno-defer-typed-holes</option></entry>
+ </row>
+
+ <row>
<entry><option>-fhelpful-errors</option></entry>
<entry>Make suggestions for mis-spelled names.</entry>
<entry>dynamic</entry>
@@ -1626,7 +1643,11 @@
<row>
<entry><option>-fwarn-typed-holes</option></entry>
- <entry>Enable <link linkend="typed-holes">holes</link> in expressions.</entry>
+ <entry>
+ Report warnings when <link linkend="typed-holes">typed hole</link>
+ errors are <link linkend="defer-type-errors">deferred until
+ runtime</link>. See <option>-fdefer-typed-holes</option>.
+ </entry>
<entry>dynamic</entry>
<entry><option>-fno-warn-typed-holes</option></entry>
</row>
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index f73a1d9980..3d9e45c8e3 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -3,7 +3,7 @@
<indexterm><primary>language, GHC</primary></indexterm>
<indexterm><primary>extensions, GHC</primary></indexterm>
As with all known Haskell systems, GHC implements some extensions to
-the language. They can all be enabled or disabled by commandline flags
+the language. They can all be enabled or disabled by command line flags
or language pragmas. By default GHC understands the most recent Haskell
version it supports, plus a handful of extensions.
</para>
@@ -8423,31 +8423,37 @@ with <option>-XNoMonoLocalBinds</option> but type inference becomes less predica
<sect1 id="typed-holes">
<title>Typed Holes</title>
-<para>Typed hole support is enabled with the option
-<option>-fwarn-typed-holes</option>, which is enabled by default.</para>
-
<para>
-This option allows special placeholders, written with a leading underscore (e.g. "<literal>_</literal>",
-"<literal>_foo</literal>", "<literal>_bar</literal>"), to be used as an expression.
-During compilation these holes will generate an error message describing what type is expected there,
-information about the origin of any free type variables, and a list of local bindings
-that might help fill the hole with actual code.
+Typed holes are a feature of GHC that allows special placeholders written with
+a leading underscore (e.g., "<literal>_</literal>", "<literal>_foo</literal>",
+"<literal>_bar</literal>"), to be used as expressions. During compilation these
+holes will generate an error message that describes which type is expected at
+the hole's location, information about the origin of any free type variables,
+and a list of local bindings that might help fill the hole with actual code.
+Typed holes are always enabled in GHC.
</para>
<para>
-The goal of the typed holes warning is not to change the type system, but to help with writing Haskell
-code. Typed holes can be used to obtain extra information from the type checker, which might otherwise be hard
-to get.
-Normally, using GHCi, users can inspect the (inferred) type signatures of all top-level bindings.
-However, this method is less convenient with terms which are not defined on top-level or
-inside complex expressions. Holes allow to check the type of the term you're about to write.
+The goal of typed holes is to help with writing Haskell code rather than to
+change the type system. Typed holes can be used to obtain extra information
+from the type checker, which might otherwise be hard to get. Normally, using
+GHCi, users can inspect the (inferred) type signatures of all top-level
+bindings. However, this method is less convenient with terms that are not
+defined on top-level or inside complex expressions. Holes allow the user to
+check the type of the term they are about to write.
</para>
<para>
-Holes work together well with <link linkend="defer-type-errors">deferring type errors to runtime</link>:
-with <literal>-fdefer-type-errors</literal>, the error from a hole is also deferred, effctively making the hole
-typecheck just like <literal>undefined</literal>, but with the added benefit that it will show its warning message
-if it gets evaluated. This way, other parts of the code can still be executed and tested.
+To run and test a piece of code containing holes, use the
+<literal>-fdefer-typed-holes</literal> flag. This flag defers errors
+produced by typed holes and converts them into warnings. The result is that
+typed hole errors are converted into warnings (controlled by
+<literal>-fwarn-typed-holes</literal>). 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. 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>
<para>
@@ -8558,6 +8564,15 @@ main = print "b"
warnings, but will not prevent compilation.
</para>
<para>
+ This flag implies the <literal>-fdefer-typed-holes</literal> flag,
+ which enables this behaviour for <link linkend="typed-holes">typed holes
+ </link>. Should you so wish, it is possible to enable
+ <literal>-fdefer-type-errors</literal> without enabling
+ <literal>-fdefer-typed-holes</literal>, by explicitly specifying
+ <literal>-fno-defer-typed-holes</literal> on the commandline after the
+ <literal>-fdefer-type-errors</literal> flag.
+ </para>
+ <para>
At runtime, whenever a term containing a type error would need to be
evaluated, the error is converted into a runtime exception.
Note that type errors are deferred as much as possible during runtime, but
diff --git a/docs/users_guide/using.xml b/docs/users_guide/using.xml
index a3b3d05d08..309be8cf23 100644
--- a/docs/users_guide/using.xml
+++ b/docs/users_guide/using.xml
@@ -1131,14 +1131,11 @@ test.hs:(5,4)-(6,7):
<indexterm><primary><option>-fwarn-typed-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="typed-holes"/></para>
+ <para>
+ Determines whether the compiler reports typed holes warnings. Has
+ no effect unless typed holes errors are deferred until runtime.
+ See <xref linkend="typed-holes"/> and <xref linkend="defer-type-errors"/>
+ </para>
<para>This warning is on by default.</para>
</listitem>
@@ -1160,6 +1157,27 @@ test.hs:(5,4)-(6,7):
</varlistentry>
<varlistentry>
+ <term><option>-fdefer-typed-holes</option>:</term>
+ <listitem>
+ <indexterm><primary><option>-fdefer-typed-holes</option></primary>
+ </indexterm>
+ <indexterm><primary>warnings</primary></indexterm>
+ <para>
+ Defer typed holes errors until runtime. This will turn the errors
+ produced by <link linked="typed-holes">typed holes</link> into
+ warnings. Using a value that depends on a typed hole produces a
+ runtime error, the same as <option>-fdefer-type-errors</option>
+ (which implies this option). See <xref linkend="typed-holes"/>
+ and <xref linkend="defer-type-errors"/>.
+ </para>
+ <para>
+ Implied by <option>-fdefer-type-errors</option>. See also
+ <option>-fwarn-typed-holes</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-fhelpful-errors</option>:</term>
<listitem>
<indexterm><primary><option>-fhelpful-errors</option></primary>
diff --git a/testsuite/tests/module/mod71.stderr b/testsuite/tests/module/mod71.stderr
index f42d17de0c..7cf7e0bf7b 100644
--- a/testsuite/tests/module/mod71.stderr
+++ b/testsuite/tests/module/mod71.stderr
@@ -1,2 +1,11 @@
-mod71.hs:4:9: Pattern syntax in expression context: _
+mod71.hs:4:9:
+ Found hole ‘_’ with type: t1
+ Where: ‘t1’ is a rigid type variable bound by
+ the inferred type of f :: (t1 -> a -> t) -> t at mod71.hs:4:1
+ Relevant bindings include
+ x :: t1 -> a -> t (bound at mod71.hs:4:3)
+ f :: (t1 -> a -> t) -> t (bound at mod71.hs:4:1)
+ In the first argument of ‘x’, namely ‘_’
+ In the expression: x _ 1
+ In an equation for ‘f’: f x = x _ 1
diff --git a/testsuite/tests/rename/should_fail/rnfail016.stderr b/testsuite/tests/rename/should_fail/rnfail016.stderr
index b24db3cf6a..eeeddfa58c 100644
--- a/testsuite/tests/rename/should_fail/rnfail016.stderr
+++ b/testsuite/tests/rename/should_fail/rnfail016.stderr
@@ -2,5 +2,3 @@
rnfail016.hs:6:7: Pattern syntax in expression context: x@x
rnfail016.hs:7:7: Pattern syntax in expression context: ~x
-
-rnfail016.hs:8:7: Pattern syntax in expression context: _
diff --git a/testsuite/tests/typecheck/should_compile/T9497a.hs b/testsuite/tests/typecheck/should_compile/T9497a.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T9497a.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_compile/T9497a.stderr b/testsuite/tests/typecheck/should_compile/T9497a.stderr
new file mode 100644
index 0000000000..763fbaea33
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T9497a.stderr
@@ -0,0 +1,6 @@
+
+T9497a.hs:2:8: Warning:
+ Found hole ‘_main’ with type: IO ()
+ Relevant bindings include main :: IO () (bound at T9497a.hs:2:1)
+ In the expression: _main
+ In an equation for ‘main’: main = _main
diff --git a/testsuite/tests/typecheck/should_compile/T9497b.hs b/testsuite/tests/typecheck/should_compile/T9497b.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T9497b.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_compile/T9497b.stderr b/testsuite/tests/typecheck/should_compile/T9497b.stderr
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T9497b.stderr
diff --git a/testsuite/tests/typecheck/should_compile/T9497c.hs b/testsuite/tests/typecheck/should_compile/T9497c.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T9497c.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_compile/T9497c.stderr b/testsuite/tests/typecheck/should_compile/T9497c.stderr
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T9497c.stderr
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T
index 8acfa4aa53..b16ff4309d 100644
--- a/testsuite/tests/typecheck/should_compile/all.T
+++ b/testsuite/tests/typecheck/should_compile/all.T
@@ -428,3 +428,6 @@ test('T9404b', normal, compile, [''])
test('T7220', normal, compile, [''])
test('T7220a', normal, compile_fail, [''])
test('T9151', normal, compile, [''])
+test('T9497a', normal, compile, ['-fdefer-typed-holes'])
+test('T9497b', normal, compile, ['-fdefer-typed-holes -fno-warn-typed-holes'])
+test('T9497c', normal, compile, ['-fdefer-type-errors -fno-warn-typed-holes'])
diff --git a/testsuite/tests/typecheck/should_fail/T9497d.hs b/testsuite/tests/typecheck/should_fail/T9497d.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T9497d.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_fail/T9497d.stderr b/testsuite/tests/typecheck/should_fail/T9497d.stderr
new file mode 100644
index 0000000000..4f18ce9497
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/T9497d.stderr
@@ -0,0 +1,6 @@
+
+T9497d.hs:2:8:
+ Found hole ‘_main’ with type: IO ()
+ Relevant bindings include main :: IO () (bound at T9497d.hs:2:1)
+ In the expression: _main
+ In an equation for ‘main’: main = _main
diff --git a/testsuite/tests/typecheck/should_fail/all.T b/testsuite/tests/typecheck/should_fail/all.T
index 96396d27c4..81ea3d25b9 100644
--- a/testsuite/tests/typecheck/should_fail/all.T
+++ b/testsuite/tests/typecheck/should_fail/all.T
@@ -343,3 +343,4 @@ test('T9774', normal, compile_fail, [''])
test('T9318', normal, compile_fail, [''])
test('T9201', normal, compile_fail, [''])
test('T9109', normal, compile_fail, [''])
+test('T9497d', normal, compile_fail, ['-fdefer-type-errors -fno-defer-typed-holes'])
diff --git a/testsuite/tests/typecheck/should_run/T9497a-run.hs b/testsuite/tests/typecheck/should_run/T9497a-run.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/T9497a-run.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_run/T9497a-run.stderr b/testsuite/tests/typecheck/should_run/T9497a-run.stderr
new file mode 100644
index 0000000000..aae24cf396
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/T9497a-run.stderr
@@ -0,0 +1,7 @@
+T9497a-run: T9497a-run.hs:2:8:
+ Found hole ‘_main’ with type: IO ()
+ Relevant bindings include
+ main :: IO () (bound at T9497a-run.hs:2:1)
+ In the expression: _main
+ In an equation for ‘main’: main = _main
+(deferred type error)
diff --git a/testsuite/tests/typecheck/should_run/T9497b-run.hs b/testsuite/tests/typecheck/should_run/T9497b-run.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/T9497b-run.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_run/T9497b-run.stderr b/testsuite/tests/typecheck/should_run/T9497b-run.stderr
new file mode 100644
index 0000000000..62d858f879
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/T9497b-run.stderr
@@ -0,0 +1,7 @@
+T9497b-run: T9497b-run.hs:2:8:
+ Found hole ‘_main’ with type: IO ()
+ Relevant bindings include
+ main :: IO () (bound at T9497b-run.hs:2:1)
+ In the expression: _main
+ In an equation for ‘main’: main = _main
+(deferred type error)
diff --git a/testsuite/tests/typecheck/should_run/T9497c-run.hs b/testsuite/tests/typecheck/should_run/T9497c-run.hs
new file mode 100644
index 0000000000..fa30912352
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/T9497c-run.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = _main
diff --git a/testsuite/tests/typecheck/should_run/T9497c-run.stderr b/testsuite/tests/typecheck/should_run/T9497c-run.stderr
new file mode 100644
index 0000000000..be5d9472f7
--- /dev/null
+++ b/testsuite/tests/typecheck/should_run/T9497c-run.stderr
@@ -0,0 +1,7 @@
+T9497c-run: T9497c-run.hs:2:8:
+ Found hole ‘_main’ with type: IO ()
+ Relevant bindings include
+ main :: IO () (bound at T9497c-run.hs:2:1)
+ In the expression: _main
+ In an equation for ‘main’: main = _main
+(deferred type error)
diff --git a/testsuite/tests/typecheck/should_run/all.T b/testsuite/tests/typecheck/should_run/all.T
index 5da7c8b169..53c97ea1a8 100755
--- a/testsuite/tests/typecheck/should_run/all.T
+++ b/testsuite/tests/typecheck/should_run/all.T
@@ -112,3 +112,6 @@ test('TcTypeNatSimpleRun', normal, compile_and_run, [''])
test('T8119', normal, ghci_script, ['T8119.script'])
test('T8492', normal, compile_and_run, [''])
test('T8739', normal, compile_and_run, [''])
+test('T9497a-run', [exit_code(1)], compile_and_run, ['-fdefer-typed-holes'])
+test('T9497b-run', [exit_code(1)], compile_and_run, ['-fdefer-typed-holes -fno-warn-typed-holes'])
+test('T9497c-run', [exit_code(1)], compile_and_run, ['-fdefer-type-errors -fno-warn-typed-holes'])