[GHC] #9049: Expose srcLoc from the assertion architecture to allow better error messages

GHC ghc-devs at haskell.org
Tue Apr 29 02:13:28 UTC 2014


#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


More information about the ghc-tickets mailing list