Skip to content

Record explanations for insolubility of constraints rather than reconstitute the problem after the fact

Currently, when an unsolved Wanted constraint remains, in order to report an error message, we put a lot of effort into reconstituting the reason why we couldn't solve it.

To take a random example from GHC.Tc.Errors.reportWanteds, when we can't solve a Coercible/(~#R) constraint, we look to see if that might have been because a newtype constructor wasn't in scope (perhaps we imported the newtype but not its constructor), see GHC.Tc.Errors.mkCoercibleExplanation. Or perhaps we want to solve Coercible (f a) (f b) from Coercible a b, but we don't know that f has Representational role, so we report an explanation involving roles.

This seems like a duplication of effort to me: instead of having the constraint solver leave a record of what it tried to do, we instead reverse-engineer what we think the constraint solver might have done, after the fact.

I don't have a concrete proposal, but perhaps we could add a field to the CtWanted constructor of CtEvidence, say ctev_explanations, which would be a set of messages that could be printed if we end up not being able to solve the constraint. This would give a mechanism through which the constraint solver could explain itself.

Edited by sheaf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information