
On Mon, Jan 18, 2016, at 15:19, David Feuer wrote:
I love the idea of adding support for such a warning, but I think core2core is likely too late to do the job properly. The instance resolution information is (currently, at least) thrown out altogether once the type checker finishes its job. And even the slightest bit of inlining of external modules could give false positives.
This was my main concern as well. I don't recall if ghc performs any inlining before running the core2core pipeline, but it's certainly fragile even wrt the pipeline order.
I would think the easiest way would be to add a "suppressed instance" structure to the type checker. It would basically be a stripped-down analogue of the big instance database the type checker uses for instance resolution. When resolving an instance, the type checker would first check the suppressed instance set for it; if it found it there, it would fail or warn as appropriate. So I could write something like
{-# SuppressInstance Functor ((,) a) #-}
But I could also write something more subtle like
{-# WarnInstance Semigroup v => Monoid (HashMap k v) #-}
which would only warn me if I use the Monoid instance for a HashMap whose values form a semigroup.
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.