RE: calling fail in Q monad gives uninformative error message, anderror causes panic
Tim and I want to tidy up the error-reporting interface in Template Haskell. The goal is that a TH user should be able to control the error messages that appear. Here's a proposal qReport :: Severity -> String -> Q () -- Report an error or warning -- ...but carry on; use 'fail' to stop fail :: String -> Q a -- Part of Monad class qRecover :: (String -> [(Severity,Loc,String)] -> Q a) -> Q a -> Q a -- Recover from the monadic 'fail' -- The first arg is the error handler -- The first String arg to the handler is what was passed to 'fail' qReports :: [(Severity,Loc,String)] -> Q () data Severity = Error | Warning qGetLoc :: Q Loc qGetModule :: Q ModuleName qWithLoc :: Loc -> Q a -> Q a data Loc = Loc FileName LineNumber CharPos The idea is that qReport dumps a message into the monad (but does not print it yet) with an indication of severity. qReport does not cause monadic failure... you can dump in as many error messages as you like. qReport adds location information from the monad to the message. fail causes monadic failure. qRecover recovers from monadic failure, giving to the recovery routine both the string passed to fail, and the accumulated messages from the enclosed computation. It can use qReports to dump all those messages back into the monad -- or it can just discard them if it wants. At a splice point, the typechecker runs the Q computation. If the result is monadic success, it continues with the returned results. If the result is monadic failure, the splice fails too. (That does not result in any panic -- the type checker is designed to fail, and recover at some outer point.) In both cases, the messages from the Q monad are dumped into the typechecker's message pile. One open question. If you say qReport Error "Bad thing" fail "wuggle" in the Q monad, do you get two type error messages ("Bad thing" and "wuggle") or just one? I can think of three possibilities a) fail s is treated as adding an error message with Severity = Error b) fail s adds no error messages c) fail s behaves like (b) if (null s) and like (a) otherwise. The advantage of (b) and (c) is that you can add a whole bunch of error messages, and then fail, without adding yet another. Comments? Once we have an interface agreed, it won't be hard to implement. Simon | -----Original Message----- | From: glasgow-haskell-bugs-bounces@haskell.org [mailto:glasgow-haskell-bugs- | bounces@haskell.org] On Behalf Of Duncan Coutts | Sent: 23 June 2004 01:13 | To: glasgow-haskell-bugs@haskell.org | Subject: TH: calling fail in Q monad gives uninformative error message, anderror causes panic | | | ghc makes it's own type checker monad TcM an instance of the Quasi class | (which is rather cunning), however this means that if the user calls the | Monad function 'fail' then the internal TcM fail method gets called. | This monad (IOEnv) was never meant to fail (see | ghc/compiler/utils/IOEnv.hs/) so the error message is: | | Exception when trying to run compile-time code: | Code: genex_count | Exn: user error (IOEnv failure) | | Of course the user code should be using 'report', but if you're using | old code, or code that is generic in the monad it uses then people will | end up calling fail. | | Perhaps the thing to do is to wrap splices in an exception handler and | convert 'fail's into a 'report' instead. | | The same should probably be done for errors raised in pure code by | calling 'error'. At the moment it gives an overly panicky report | (although at least it passes the user's error message through): | | ghc-6.3: panic! (the `impossible' happened, GHC version 6.3): | where clauses & gaurds not yet supprted in function definitions | | The error message there is generated by my code (hence the spelling | errors :-) ). | | Duncan | | _______________________________________________ | Glasgow-haskell-bugs mailing list | Glasgow-haskell-bugs@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
participants (1)
-
Simon Peyton-Jones