I seem to remember that there was some debate about the overall architecture:
- something similar to the current exception hierarchy but for errors, with extensive use of
- a monolithic error type which could necessitate circular module dependencies.
- a modular approach where each stage of the compiler has its own error type, and then the GHC driver combines them in a big sum type.
I gather that the last approach was chosen, and
GhcMessage is the sum type that combines the errors from each stage?
I gather that the last approach was chosen, and GhcMessage is the sum type that combines the errors from each stage?
Yes, and sorry if this wasn’t explicit enough in the blog post. The rule of thumb we have tried to follow is that functions which deal with only one part of the pipeline (i.e. parsing, or typecheck-rename, desugaring etc) would return a specialised diagnostic type (think
PsMessage etc), whereas functions that deals with multiple phases at once or top-level functions would return a
GhcMessage as they need to collect results from different parts of the pipeline.
Last but not least, there is also the exception-handling story. Historically GHC was never very consistent in the way diagnostics are reported: in some places, we accumulate them in a monadic context, sometimes they get thrown as exceptions (sigh), which is another place where the
GhcMessage is handy, because we don’t know from where the exception will be thrown, so we need an umbrella type to be able to handle each different diagnostic type GHC might report.
I hope it helps!