Pragma to identify non-singleton classes
Motivation
We've seen a few places recently where it would be useful to mark classes as non-singletons, e.g. reflection
could define class {-# NON_SINGLETON #-} Given a
.
This would mean:
- The specialiser would never specialise for the class (but might abstract over free dictionary variables of that type instead, see #23282 (comment 500933)).
- Shortcut solving (
-fsolve-constant-dicts
) would be disabled for the class. - Hence
withDict
should work reliably for such classes (see #21575 (comment 520219)). - Using incoherent instances for the class would be less risky, because once type inference had determined an instance it would not change during optimisation (see #23172 (comment 500109)).
- This would provide a more robust way to prevent specialisation of incoherent instances than attaching
nospec
with-fno-specialise-incoherents
as introduced in !10748 (merged) (see #23429, #23560).
The IP
class backing implicit parameters effectively already has this behaviour, as I understand it.
We should more clearly document that in the absence of the pragma, the optimiser will assume classes are singletons, and hence incoherent instances / withDict
are potentially unsafe.
Open questions
- Would this suffice for
reflection
? As far as I can see it would merely need to mark theReifies
andGiven
classes as non-singletons, but I'm not sure if this might end up having a performance impact. Perhaps @RyanGlScott could comment? - Would this suffice for @cactus' use case?
- I'm unsure of the best concrete syntax for this, are pragmas or modifiers the right approach?
- Perhaps GHC should emit a warning or error if
withDict
was used for a normal non-singleton class?