|Version 9 (modified by 5 years ago) (diff),|
Deferring compilation type errors to runtime
This page describes the
-fwarn-type-errors flag, currently implemented in the ghc branch
Ticket #5624 tracks this feature request.
While developing, sometimes it is desirable to allow compilation to succeed even if there are type errors in the code. Consider the following case:
module Main where a :: Int a = 'a' main = print "b"
a is ill-typed, it is not used in the end, so if all that we're
interested in is
main it is handy to be able to ignore the problems in
Since we treat type equalities as evidence, this is relatively simple. Whenever
we run into a type mismatch in
TcUnify, we would normally just emit an error. But it
is always safe to defer the mismatch to the main constraint solver. If we do
a will get transformed into
$co :: Int ~# Char $co = ... a :: Int a = 'a' `cast` $co
The constraint solver would realize that
co is an insoluble constraint, and
emit an error. But we can also replace the right-hand side
co with a runtime error call. This allows the program
to compile, and it will run fine unless we evaluate
a. Since coercions are
unboxed they will be eagerly evaluated if used, so laziness will not "get on
The first step is to make sure that
TcUnify does not ever fail with a type
error; instead, we call
uType_defer to defer the unification to the constraint
In the constraint solver, we call
reportUnsolved with any remaining unsolved
constraints. At this stage, if we are not deferring errors, we simply make the
errors for each unsolved constraint and throw them. If we are deferring errors,
we make the errors for each constraint and then set the evidence binder of each
unsolved constraint to be a runtime error that emits the type error message we
just created. This is done by
typecheck/TcErrors. Note that
reportTidyWanteds has some shuffling to do,
because when we are not deferring errors we group certain errors, or we don't
report all the errors. But when we are deferring we really want to have
(at least) one error for every coercion.
For simplicity, we defer errors from
TcUnify to the constraint solver even
-fwarn-type-errors is not on; in that case, we will simply fail in the
constraint solver, rather than directly in the unifier.
This means that some type error messages change, even without
In particular, many tests from the testsuite need to have their output adapted.
Currently we cannot defer kind errors because we do not create coercions for kind equalities. This might change in the near future, though, in which case we could use the same strategy to defer kind errors to runtime.