Template Haskell fail Messages not Getting Through
There is (I believe) a mistake in GHC's template Haskell implementation int the way the fail member is handled. The error messages get eaten and replaced with a cryptic reference to an "IOEnv failure". For example (at the "ghci -fth" prompt):
Prelude> let doit = fail "Code not written yet" :: Language.Haskell.TH.ExpQ
Loading package template-haskell ... linking ... done.
Prelude> $(doit)
<interactive>:1:2:
Exception when trying to run compile-time code:
user error (IOEnv failure)
Code: doit
In the expression: $[splice]doit
In the definition of `it': it = $[splice]doit
Prelude>
The problem seems to be that GHC runs the template code in the IOEnv monad (compiler/typecheck/TcSplite.lhs) whose fail implementation (compiler/utils/IOEnv.hs) eats its argument and instead raises "userError "IOEnv failure"".
I put a patch together for this, and will submit it soon (i.e., as soon as I finish reading the pages on how to do so). With the patch, the above examples becomes:
Prelude> let doit = fail "Code not written yet" :: Language.Haskell.TH.ExpQ
Loading package template-haskell ... linking ... done.
Prelude> $(doit)
<interactive>:1:2: Code not written yet
Prelude>
This is achieved through changing the fail implementation for the Q monad to first log the message with report before passing control through the fail member of the underlying Quasi instance (IOEnv in this case) and changing the exception handling code around the running of the template code to gracefully handle exceptions raised in such a manner (i.e., print out the logged message).
It is a bit hackish, but it was the only way I could see to do this with out changing the fail implementation for IOEnv (I assume it was written the way it is for a reason -- possibly to avoid spamming the user with messages regarding compiler problems -- although it does seems strange) or introducing an additional function into the Q monad (such as giveUp from "Notes on Template Haskell Version 2").
Trac metadata
Trac field | Value |
---|---|
Version | 6.6 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Template Haskell |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Unknown |
Architecture | Unknown |