Skip to content

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