<div dir="ltr"><div>Hello everyone,</div><div><br></div><div>I'm happy to report that I have implemented a compatibility layer in the ghc-tcplugin-api library which provides type-family rewriting functionality on GHC 9.0 and 9.2.</div><div>This means that plugin authors should now be able to use the exact same API from GHC 9.0 onwards (and in particular, without waiting for a version of GHC containing the new implementation of type-family rewriting plugins).</div><div><br></div><div> To refresh your memory, writing a type-checking plugin with this library currently consists of the provision of a record<br></div><div><br></div><div></div><div><span style="font-family:monospace">data TcPlugin = forall s. TcPlugin<br>  { tcPluginInit    :: TcPluginM Init s<br>  , tcPluginSolve   :: s -> TcPluginSolver<br>  , tcPluginRewrite :: s -> UniqFM TyCon TcPluginRewriter<br>  , tcPluginStop    :: s -> TcPluginM Stop ()<br>  }</span></div><div><br></div><div>with the following type synonyms:<br></div><div><br></div><div></div><div><span style="font-family:monospace">type TcPluginSolver<br>  =  [GHC.Ct] -- ^ Givens<br>  -> [GHC.Ct] -- ^ Wanteds<br>  -> TcPluginM Solve TcPluginSolveResult</span></div><div><br></div><div>Note that Deriveds are no longer passed explicitly. (It is possible to retrieve
the Derived constraints

 from the TcPluginM Solve monad; as they are not commonly used, it made sense to make them less conspicuous.)<br></div><div><br></div><div><span style="font-family:monospace">type TcPluginRewriter<br>  =  [GHC.Ct]     -- ^ Givens<br>  -> [GHC.Type]   -- ^ Type family arguments (saturated)<br>  -> TcPluginM Rewrite TcPluginRewriteResult</span></div><div><br></div><div><br></div><div>On GHC 9.0 and 9.2, the tcPluginRewrite function will get hooked in as a pre-pass of the user-supplied tcPluginSolve function.</div><div>There are small differences in behaviour that arise from solver plugins not always getting a chance to run when GHC can solve the wanteds on its own, 
but I expect this to have minimal impact. <br></div><div>On top of this, I expect (but have not measured) a performance degradation compared to the "native" plugin type-family rewriting functionality, as the solver plugin must traverse all constraints to find type-family applications.<br></div><div><br></div><div>I have not tested this compatibility layer extensively, so I welcome all feedback from plugin authors.</div><div><br></div><div>Note that I have also reduced the amount of re-exported datatype constructors and accessors in an attempt to improve cross compatibility.</div><div>Please let me know of any difficulties that you encounter as a consequence, and I will endeavour to re-export cross-compatible non-internal definitions.</div><div><br></div><div>Thanks,</div><div><br></div><div>Sam<br></div></div>