Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information