
#9049: Expose srcLoc from the assertion architecture to allow better error messages ------------------------------------+------------------------------------- Reporter: nh2 | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- Assertions give great error messages by including file name and line, but they are disabled for optimisation. While there is a compiler flag to turn them on even in presence of optimisation, this is an awkward external way to simply attach a useful error location to something like `error`. It would be great if we could decouple getting the current `srcLoc` from assertions, and making it available for good error messages. It is currently possible to do this using TemplateHaskell (e.g. the `placeholders` package) or `CPP`, but both are inconvenient for technical reasons (such as breaking tooling) and do not enjoy widespread use. It seems a shame that the architecture for annotated error messages is already there, but only available through a mechanism that is disabled for optimisation (or at least "intended" to be disabled for optimisation). Notably, we have the same architecture available for pattern mach failures: {{{ f x | x > 0 = "foo" main = putStrLn (f (-1)) -- gives srcLoc'd pattern match error message }}} {{{ f x | x > 0 = "foo" f _ = error "f needs a positive number" main = putStrLn (f (-1)) -- does not give a srcLoc'd error message }}} It seems non-sensical that your try to write a better error message (here using `error`) yields in fact a less-helpful error message. I completely agree that one can aid bug-fixing by writing globally unique arguments to `error` or using TH, but from an engineering perspective, a little bit of help from the language/compiler side can improve the situation a lot, and in other languages this is acknowledged and used to everybody's benefit. There are some alternatives we might consider, such as * exposing `srcLoc :: String` that gives an `assert`-style location at the lexical position of its occurrence * adding an `error`-like function that behaves like `error` but also prints a source location Arguably `srcLoc :: String` breaks equational reasoning on the ''syntactic'' level, as `let x = srcLoc in (x, x)` and `(srcLoc, srcLoc)` have different values. However, looking at it from a program execution point of view, referential transparency is preserved since once compiled, any function using `srcLoc` will always return the same location. I believe that offering ''some'' kind of improvement over the dreaded `error` or `Prelude: undefined` should be easy to implement, but let's hear what the people who actually know the compiler think about it. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler