Cancelling compiles using asynchronous exceptions while TH is being run can cause incorrect compile errors
We run the following bit of code while evaluating TH:
; either_tval <- tryAllM $
setSrcSpan expr_span $ -- Set the span so that qLocation can
-- see where this splice is
do { mb_result <- run_and_convert expr_span hval
; case mb_result of
Left err -> failWithTc err
Right result -> do { traceTc "Got HsSyn result:" (ppr_hs result)
; return $! result } }
Note the tryAllM
. In particular, it has the following comment:
-- XXX We shouldn't be catching everything, e.g. timeouts
tryAllM :: IOEnv env r -> IOEnv env (Either SomeException r)
Clearly whoever wrote this knew that this was the incorrect behavior.
In particular, this affects ghcide, which uses async exceptions to cancel compiles that are no longer valid/necessary. This results in a spurious "Exception when trying to run compile-time code" compile error being shown to the user, while in fact there is no problem with the users code.
This is because the exception that ghcide uses to cancel the compile is caught by tryAllM
and then re-raised as
a type-checker error.
Edited by Zubin