Error message infrastructure
I have just spent a couple of hours wrestling with the new error message infrastructure for the typechecker. Here are some thoughts and questions.
To be clear, the direction of travel is great -- this is all about detail.
-
Surely we should have
instance Outputable e => Outputable (Messages e) instance Outputable e => Outputable (MsgEnvelope e)
I needed it today, and although took me over an hour of faff to figure out how to do it, it's not so hard
instance Diagnostic e => Outputable (Messages e) where ppr msgs = braces (vcat (map ppr_one (bagToList (getMessages msgs)))) where ppr_one :: MsgEnvelope e -> SDoc ppr_one envelope = ppr_diag (errMsgDiagnostic envelope) ppr_diag :: e -> SDoc ppr_diag diag = vcat [ ppr (diagnosticReason diag) , nest 2 (vcat (unDecorated (diagnosticMessage diag))) ]
This could be improved.
-
This is newtype poorly named:
newtype Messages e = Messages { getMessages :: Bag (MsgEnvelope e) }
Either the newtype should be
MsgEnvelopes e
or the contents should beBag (Message e)
. -
We have in
GHC.Tc.Errors.Types
:data TcRnMessage where TcRnUnknownMessage :: (Diagnostic a, Typeable a) => a -> TcRnMessage TcRnMessageWithInfo :: !UnitState -> !TcRnMessageDetailed -> TcRnMessage TcRnSolverReport :: [ReportWithCtxt] -> DiagnosticReason -> [GhcHint] -> TcRnMessage ...lots more error-secific-constructors... data TcRnMessageDetailed = TcRnMessageDetailed !ErrInfo !TcRnMessage
Questions
- Can't we just inline
TcRnMessageDetailed
intoTcRnMessageWithInfo
? - How would I choose between
TcRnUnknownMessage
andTcRnMessageWithInfo
and an error-specific constructor?
- Can't we just inline
-
Also in
GHC.Tc.Errors.Types
:data ReportWithCtxt = ReportWithCtxt ReportErrCtxt TcReportMsg data TcReportMsg where ...lots *more* error-specific constructors....
- Why do we need
TcRnMessage
andTcReportMsg
? Ah.. maybe those are solver-specific errors? But then calll itTcSolverMessage
etc. - And put all the solver-specific stuff in
TcRnSolverReport
; at the momentTcRnInaccessibleCode
sticks out like a sore thumb. - Why does
TcRnSolverReport
take a list of solver errors? It really has one error, plus a list of supplementary information, a bit like your various "WithInfo" variants, doesn't it?
- Why do we need
Generally, the data types are so large that I found it really helpful to write down the above sketches, just to keep them in my head. We might consider doing that in some way.