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.