7

I know that I can cause a compile-time error by calling fail from a splice, but is it possible to only generate a warning? In particular I would like it to be possible to turn this warning into an error when compiling with -Werror.

Essentially what I'm trying to do is this:

todo :: Q Exp
todo = do
    -- emit warning somehow

    loc <- location
    let message = ... -- generate message based on loc
    [| error $(litE (stringL message)) |]

The idea is to use this instead of undefined while coding, but make sure it doesn't sneak its way into production code by compiling with -Werror.

myFunc x | isSimpleCase x = 42
         | otherwise = $todo
hammar
  • 138,522
  • 17
  • 304
  • 385

3 Answers3

5

Turns out the function I was after was the Template Haskell function report. Its type signature was in the documentation, but I had to read the source code to figure out what it did. The TH documentation sure could use some improvements.

Anyway, my todo placeholder is now working perfectly, and I'll put something up on Hackage soon if anyone is interested.

hammar
  • 138,522
  • 17
  • 304
  • 385
2

I don't believe this is possible naively from TH, but it is a really cool idea.

One way to implement it would be via bindings to the GHC-API warning and debug output or error functions.

E.g. to pretend to be GHC,

import Panic
main = sorry "help!"

produces

$ ./A                                
A: A: sorry! (unimplemented feature or known bug)
  (GHC version 7.0.2 for x86_64-unknown-linux):
    help!

Constructing GHC warnings should work similarly, checking if -Werror is set, and you could clean up the API to be quite useful.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
  • The warning functions in GHC-API all require access to the parsed command line flags of GHC, so that looks fairly hairy, but I found a TH function `report` which seems to do what I need. – hammar Apr 25 '11 at 04:32
1

To emit warnings from Template Haskell splices, you can use reportWarning :: String -> Q ().

It already includes the location (line and column). You can implement your todo function simply by:

todo :: Q Exp
todo = do
  reportWarning "TODO"
  [| undefined |]

Further information

@hammar's answer indicates the function report. It has been deprecated since GHC 7.6 (2012) and will possibly be removed from the API in the near future. (However, report is still available on GHC 7.10 and on GHC master branch as of 2015.)

Use reportError to report an error and carry on with the Q computation (ultimately failing compilation anyway).

Use fail to stop with an error (GHC ≤ 7.10). That might not apply on GHC 8.0.

Rudy Matela
  • 6,310
  • 2
  • 32
  • 37