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

#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

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Changes (by simonpj): * cc: augustss (added) Comment: This is a sensible, and long-running feature request. I can't find other tickets about it, which is puzzling, but see [wiki:ExplicitCallStack] for lots of material. I thought that Lennart was muttering about this too, but I can't find the trail. It's possible I may get some time/effort to work in it this summer, but it'd be great to evolve a clear design first. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

I thought that Lennart was muttering about this too, but I can't find
#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by refold): Replying to [comment:1 simonpj]: the trail. I think you're referring to these posts: http://augustss.blogspot.se/2014/04/a-small-haskell-extension.html http://augustss.blogspot.se/2014/04/haskell-error-reporting-with- locations_5.html -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): Simon Marlow's response is this: "Compile your program with `-prof`, run with `+RTS -xc`" and you'll get exactly the backtrace you want". You have to compile a profiled version of the packages you install, but you can do that by adding `--enable-pofiling` to Cabal, and you can put that in your `~/.cabal` file. Doesn't that do it? Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by nh2): Not really. In my view giving this kind of good error message really doesn't have to do much with ''profiling''. Sure, profiling currently improves error messages, but ideally (and practically) I don't want to compile with profiling to get a very orthogonal feature. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by carter): am i correct in understanding that the current state of things is a) the best option for now is to build with profiling? b) the feature request will be subsumed by the work on stacktraces thats (hopefully slated) for ghc 7.10? (or is there some nuance i'm missing?) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by nh2): @carter a) I believe so. b) I do not know much about the stacktraces work, but as with profiling, these kind of run-time things still seem very orthogonal to embedding a source location into an error string. Of course ''any'' form of better error messages is very appreciated, just not sure if these should be treated as the same. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonpj): I've revised [wiki:ExplicitCallStack] to discuss alternatives. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by simonmar): I actually like the wiki:ExplicitCallStack/ImplicitLocations idea, I'm just worried that if we have it then we'll have people who want location- abstracted versions of all the partial functions in base, and that's a lot of extra clutter. If we could provide the feature but draw the line at using it in APIs (except for `error`, `undefined`, `throw`, and other things that explicitly raise exceptions) then I'm all for it. I realise that then you don't get automatic `head []` locations. But it doesn't stop someone from defining their own location-abstracted `head`, or indeed making a package of location-abstracted partial functions from base. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by rodlogic): Closed #9794 as a duplicate of this one. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by rodlogic): I read the wiki:ExplicitCallStack/ImplicitLocations, and the general approach makes sense. The notion of a stack of source locations startes to loose me, though. Could you give a more explicit example? Does it basically mean that {{{show (?location :: Location)}}} below will render g's location and g's caller location? Or am I misunderstanding this? {{{ h :: [a] -> Int h as = f as g :: (?location :: Location) => [a] -> Int g as = f as f :: (?location :: Location) => [a] -> Int f [] = error ("Failure at " ++ show (?location :: Location)) f (x:xs) = ... }}} Could you point me to: 1. In what module should Location be created? 2. Where in the type checker should a Location be created? 3. Where should Locations be pushed? I can then take a closer look and come back with additional questions. @nh2 I am not sure how far along you are with this, so ping me if this is basically done already ;-) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonmar): Simon PJ: you asked what I thought about ImplicitLocations, see comment:8 above. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by gridaphobe): * owner: => gridaphobe Comment: I'm starting to work on implementing wiki:ExplicitCallStack/ImplicitLocations. If anyone else has been working on it, please let me know so I don't unnecessarily duplicate work :) simonmar: I agree that the changes to base should be kept to a minimum, at least initially. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): gridaphobe, rodlogic, are you willing to reveal your email identities? I'm having trouble connecting up email discussion with Trac personae! Thanks Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by gridaphobe): simonpj: This is Eric Seidel (eric at seidel.io). I've told trac my name and email, but it doesn't seem to expose them to others! I'd be happy to tick a "make my name+email public" box if there's one I'm missing somewhere. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonmar): Let me elaborate a bit more on my concerns here. We currently have two imperfect ways to get a stack trace: profiling and the new -g in 7.10. This is another imperfect way, with different tradeoffs. In particular, you have to modify the source code to take advantage of it (not true of the other two ways). This is fine when it's your own program, but if implicit locations start to be used in common APIs then I'm not sure the extra clutter and user confusion is worth the benefit. It's also very hard to get rid of: APIs have greater longevity than compiler features. Specifically I'm concerned that 1. Users have three imperfect solutions to choose from, which is confusing. 2. Users will want either (a) `head` to have a implicit location, or (b) for there to be a new `headLocated` function that has an implicit location. Both are bad: (a) because head no longer matches the Prelude definition, and users will be confused, and (b) because there are two versions of head, and users will be confused. Moreover, this is a slippery slope: every package author be getting bug reports wanting implicit location versions of all their partial functions. Some users will like this, others will hate it. There will be no clear policy on what to do, and different libraries will adopt different strategies, leading to yet more confusion. 3. We have one more abstraction that must be eliminated by the simplifier to get reliable performance. People who are really concerned about performance will either avoid it, or use `#ifdef` to ensure that they don't have to worry about it. 4. It relies on a very little-used extension (implicit parameters) so those who want to understand what that strange `?location` means have to go and understand implicit parameters. Were it not for this we might be able to deprecate implicit parameters as a feature that didn't turn out to be that useful. Let's think very carefully before we start down this path. It's a really useful feature for end-user code, but the problems arise when we start using it in library APIs. I'd be perfectly OK with this feature (as I mentioned in my earlier comment) as long as it does not infect library APIs except for things that are explicitly undefined, like error, undefined, and so on. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by gridaphobe): One use-case that the implicit parameters approach supports that neither -prof nor -g really do is reifying the source locations to a data structure that your haskell program can process. I imagine this is a fairly niche scenario, but it's extremely useful for embedded DSLs. I was recently working on tooling support for an EDSL used to write large (10+ kloc) programs, and providing useful diagnostic messages for the DSL was quite difficult, because I only had access to the internal AST, nothing remained of the original haskell program. I ended up writing a Core-to- Core plugin to insert the source locations that I mined from -prof, but it's a bit kludgy. This approach, on the other hand, makes it trivial for a function to get a hold of its call-site. Perhaps it would make sense to discuss the implications of this feature for library authors on the core-libraries list? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:16 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by gridaphobe): I'd also like to add that I think it would be a shame to deprecate ImplicitParams, this feature notwithstanding. ImplicitParams is niche, yes, but it's also super convenient at times, in particular for passing around some configuration without having to restructure your whole program as a reader monad. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Replying to [comment:16 gridaphobe]:
One use-case that the implicit parameters approach supports that neither -prof nor -g really do is reifying the source locations to a data structure that your haskell program can process.
Yes. So (importantly) let's not just give access to a `String` but rather to a proper data structure with line number, module, package etc. We should use the same data structures for this purpose as the `StaticPtrInfo` fields in [wiki:StaticPointers/ImplementationPlan]. The latter are not yet well fleshed out, and advertised as subject to change. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:18 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: patch request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: Phab:D578 | -------------------------------------+------------------------------------- Changes (by gridaphobe): * status: new => patch * differential: => Phab:D578 Comment: I've sent a patch that implements [wiki:ExplicitCallStack/ImplicitLocations] to Phab (https://phabricator.haskell.org/D578). -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:19 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: patch request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: Phab:D578 | -------------------------------------+------------------------------------- Comment (by rodlogic): Replying to [comment:13 simonpj]:
gridaphobe, rodlogic, are you willing to reveal your email identities? I'm having trouble connecting up email discussion with Trac personae! Thanks
Simon Simon, my real name is Yuri de Wit and my email is admin@rodlogic.net.
-- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:20 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature | Status: patch request | Milestone: Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: Phab:D578 | -------------------------------------+------------------------------------- Comment (by rodlogic): Replying to [comment:19 gridaphobe]:
I've sent a patch that implements [wiki:ExplicitCallStack/ImplicitLocations] to Phab (https://phabricator.haskell.org/D578). This is great. I would have taken me quite a while to get there.
In your patch you mention that you didn't change base at this point, could we at least change GHC.Base to use it and add a new assertMsg? This would basically cover the ASSERT macros that exist in HsVersions.h: {{{ #define ASSERT(e) if debugIsOn && not (e) then (assertPanic __FILE__ __LINE__) else #define ASSERT2(e,msg) if debugIsOn && not (e) then (assertPprPanic __FILE__ __LINE__ (msg)) else #define MASSERT(e) ASSERT(e) return () #define MASSERT2(e,msg) ASSERT2(e,msg) return () #define ASSERTM(e) do { bool <- e; MASSERT(bool) } #define ASSERTM2(e,msg) do { bool <- e; MASSERT2(bool,msg) } }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:21 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Changes (by gridaphobe): * milestone: => 7.12.1 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:22 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by simonpj): Thanks. I've added some comments to Phab:D578. Here are some other thoughts: * Could you modify [wiki:ExplicitCallStack/ImplicitLocations] to describe the exact specification of what you propose? For example, the design means that there are two new types in the `base` library, defined in `GHC.Location`: * `SrcLoc` (for a source location) * `Location` (for a stack of source locations) Both are abstract, so you can't make a new `SrcLoc` or `Location`; only GHC can do that. Is that what we want? * You can add a section on open questions too, for things you aren't sure about. * I'm very keen that `SrcLoc` is used also by the `Typeable` library (and any other reflection libraries too). Currently `Data.Typeable.Internals` defines `TyCon` which contains package/module/name information, but it should just use a `SrcLoc`. We are proposing to redesign `Typeable` anyway (see [wiki:Typeable]) so we can do this `SrcLoc` stuff at the same time * Given this broader use, is `Location` the right name? It's really more like a `SrcLocStack`. * The stack would be even better if it said something like "foo called at <location>" rather than just "<location>". That would be easy enough to implement (the information is in the `CtOrigin` of the constraint), but again the data type would need to be elaborated a bit, something like {{{ data Location = Location [(String, SrcLoc)] }}} * At a grungy level, I wonder about all the copies of the same module- name and file-name strings. Maybe the desugarer should just generate one copy and use it? Or maybe CSE should gather them up (I don't think it does so at the moment.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:23 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by gridaphobe): Replying to [comment:23 simonpj]:
* Could you modify [wiki:ExplicitCallStack/ImplicitLocations] to describe the exact specification of what you propose? For example, the design means that there are two new types in the `base` library, defined in `GHC.Location`: * `SrcLoc` (for a source location) * `Location` (for a stack of source locations) Both are abstract, so you can't make a new `SrcLoc` or `Location`; only GHC can do that. Is that what we want?
* You can add a section on open questions too, for things you aren't sure about.
* I'm very keen that `SrcLoc` is used also by the `Typeable` library (and any other reflection libraries too). Currently `Data.Typeable.Internals` defines `TyCon` which contains
Done. It's not an open question per se, but folks following this ticket may want to look at the second bullet point under Implementation Details. I'm a bit uneasy about veering that far away from the standard behavior of ImplicitParams, but I think it's worth considering at least. package/module/name information, but it should just use a `SrcLoc`. We are proposing to redesign `Typeable` anyway (see [wiki:Typeable]) so we can do this `SrcLoc` stuff at the same time
* Given this broader use, is `Location` the right name? It's really
more like a `SrcLocStack`.
* The stack would be even better if it said something like "foo called
at <location>" rather than just "<location>". That would be easy enough to implement (the information is in the `CtOrigin` of the constraint), but again the data type would need to be elaborated a bit, something like
{{{ data Location = Location [(String, SrcLoc)] }}}
In anticipation of this I've renamed `Location` to `CallStack`, but it looks like the `CtOrigin` that we get may not provide enough info. In my test-case at least, I'm getting a `TypeEqOrigin`, which isn't particularly helpful.
* At a grungy level, I wonder about all the copies of the same module- name and file-name strings. Maybe the desugarer should just generate one copy and use it? Or maybe CSE should gather them up (I don't think it does so at the moment.)
Hmm, if this is an issue my instinct would be that CSE should be responsible for cleaning up the duplicate strings. It seems to fit with the Core philosophy of having the simplifier clean up after the various other passes, and may provide benefits outside of these IP CallStacks too. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:24 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by gridaphobe): Replying to [comment:21 rodlogic]:
Replying to [comment:19 gridaphobe]:
I've sent a patch that implements [wiki:ExplicitCallStack/ImplicitLocations] to Phab (https://phabricator.haskell.org/D578). This is great. I would have taken me quite a while to get there.
In your patch you mention that you didn't change base at this point, could we at least change GHC.Base to use it and add a new assertMsg?
I'd rather keep that patch feature-only, to focus discussion around the design/implementation. But I'm happy to put together another patch, once D578 is merged, to discuss using it in base. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:25 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by simonpj): Re "the second bullet point under Implementation Details", I now understand. Good point. The issue is this: {{{ f :: (?loc :: CallStack) => IO () f = print (?location :: CallStack) }}} There are two alternatives for what to pass to `print`: * Pass the call site of `print`, pushed onto the passed-in call stack * Pass a singleton stack, just the call site of `print`, reflecting the change in name. You have implemented the first, but I think the latter would perhaps be more intuitive. Does anyone else have opinions? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:26 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by simonpj): You did not respond to bullet 5 of comment:24. I'd like to see displayed stacks looking like: {{{ foo, called at Bar.hs line 5 wim, called as Wobble.hs line 9 ...etc... }}} Currently we can get the call sites but not the function being called. I think it'd make the stacks a lot more informative. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:27 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by gridaphobe): Replying to [comment:27 simonpj]:
You did not respond to bullet 5 of comment:24. I'd like to see displayed stacks looking like: {{{ foo, called at Bar.hs line 5 wim, called as Wobble.hs line 9 ...etc... }}} Currently we can get the call sites but not the function being called. I think it'd make the stacks a lot more informative.
... but it looks like the `CtOrigin` that we get may not provide enough info. In my test-case at least, I'm getting a `TypeEqOrigin`, which isn't
Sorry, my response was jumbled in with the rename to `CallStack` particularly helpful. The `TypeEqOrigin` appears to come from call-sites; I also get an `IPOccOrigin` when the IP is used. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:28 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by simonpj): Just ignore `CtOrigin` for now. Just think about getting a more informative stack. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:29 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

Re "the second bullet point under Implementation Details", I now understand. Good point. The issue is this: {{{ f :: (?loc :: CallStack) => IO () f = print (?location :: CallStack) }}} There are two alternatives for what to pass to `print`: * Pass the call site of `print`, pushed onto the passed-in call stack * Pass a singleton stack, just the call site of `print`, reflecting
#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: patch Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by gridaphobe): Replying to [comment:26 simonpj]: the change in name.
You have implemented the first, but I think the latter would perhaps be more intuitive. Does anyone else have opinions?
The more I think about this, the more inclined I am to go with the latter behavior as well. The former, while useful, is just a bit strange. Also, from a maintainability perspective, it would probably be easier to switch from the 2nd to the 1st behavior, if needed, than vice-versa (since the 1st should allow strictly more programs to type-check). But I'd also like to hear from others. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:30 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error
messages
-------------------------------------+-------------------------------------
Reporter: nh2 | Owner: gridaphobe
Type: feature request | Status: patch
Priority: normal | Milestone: 7.12.1
Component: Compiler | Version: 7.8.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D578
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: patch => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:32 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error
messages
-------------------------------------+-------------------------------------
Reporter: nh2 | Owner: gridaphobe
Type: feature request | Status: closed
Priority: normal | Milestone: 7.12.1
Component: Compiler | Version: 7.8.2
Resolution: fixed | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D578
-------------------------------------+-------------------------------------
Comment (by Herbert Valerio Riedel

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by nh2): Related: [https://phabricator.haskell.org/D861 D861 - Use IP based CallStack in error and undefined] -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:34 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by bgamari): This has been merged to `ghc-7.10` as e3dc28046373f3183dda56b096dbebec865e3be7. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:35 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by bgamari): Unfortunately 00cd6173a620ef99739d97ac843258fee8e2dee9, which e3dc28046373f3183dda56b096dbebec865e3be7 depends upon, changes an existing interface, which we try very hard to avoid in minor releases. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:36 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by gridaphobe): Does it actually break any client packages? There was talk of building stackage with the backport to investigate. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:37 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by hvr): Replying to [comment:37 gridaphobe]:
Does it actually break any client packages? There was talk of building stackage with the backport to investigate.
Yeah, one single package from Stackage seems to be affected by this: {{{ [11 of 14] Compiling HsWalk ( HsWalk.hs, dist/build/ide-backend- server/ide-backend-server-tmp/HsWalk.o ) HsWalk.hs:136:35: Couldn't match expected type ‘SrcSpan’ with actual type ‘RealSrcSpan’ In the first argument of ‘go’, namely ‘span’ In the second argument of ‘($)’, namely ‘go span’ }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:38 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Comment (by gridaphobe): FWIW, LiquidHaskell is also broken by 00cd6173a620ef99739d97ac843258fee8e2dee9, but as a maintainer I can deal with it. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:39 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: 5273 | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Changes (by edsko): * related: => 5273 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:40 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9049: Expose srcLoc from the assertion architecture to allow better error messages -------------------------------------+------------------------------------- Reporter: nh2 | Owner: gridaphobe Type: feature request | Status: closed Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #5273, #624 | Differential Revisions: Phab:D578 -------------------------------------+------------------------------------- Changes (by bgamari): * related: 5273 => #5273, #624 Comment: One thing that we may want to consider is using this mechanism to address #624, which seeks backtraces for indefinitely blocking MVar and STM operations. The only slightly tricky thing here is that you would need to pipe the backtrace through the RTS. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9049#comment:41 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC