/testsuite/tests/tcplugins/RewritePlugin.hs

https://github.com/bgamari/ghc · Haskell · 87 lines · 66 code · 11 blank · 10 comment · 2 complexity · 68174653aded571994400102c3143ebd MD5 · raw file

  1. {-# LANGUAGE RecordWildCards #-}
  2. {-# LANGUAGE ViewPatterns #-}
  3. module RewritePlugin where
  4. -- Rewriting type family applications.
  5. -- base
  6. import Data.Maybe
  7. ( catMaybes )
  8. -- ghc
  9. import GHC.Builtin.Types
  10. ( unitTy )
  11. import GHC.Core
  12. ( Expr(Coercion) )
  13. import GHC.Core.Coercion
  14. ( Coercion, mkUnivCo )
  15. import GHC.Core.Predicate
  16. ( EqRel(NomEq), Pred(EqPred)
  17. , classifyPredType
  18. )
  19. import GHC.Core.Reduction
  20. ( Reduction(..) )
  21. import GHC.Core.TyCo.Rep
  22. ( Type, UnivCoProvenance(PluginProv) )
  23. import GHC.Core.TyCon
  24. ( TyCon )
  25. import GHC.Core.Type
  26. ( eqType, mkTyConApp, splitTyConApp_maybe )
  27. import GHC.Plugins
  28. ( Plugin )
  29. import GHC.Tc.Plugin
  30. ( TcPluginM
  31. , unsafeTcPluginTcM
  32. )
  33. import GHC.Tc.Types
  34. ( RewriteEnv
  35. , TcPluginRewriter, TcPluginRewriteResult(..)
  36. )
  37. import GHC.Tc.Types.Constraint
  38. ( Ct(..), CanEqLHS(..)
  39. , ctPred
  40. )
  41. import GHC.Tc.Types.Evidence
  42. ( EvTerm(EvExpr), Role(Nominal) )
  43. import GHC.Types.Unique.FM
  44. ( UniqFM, listToUFM )
  45. -- common
  46. import Common
  47. ( PluginDefs(..)
  48. , mkPlugin, don'tSolve
  49. )
  50. --------------------------------------------------------------------------------
  51. -- This plugin rewrites @Add a Zero@ to @a@ and @Add Zero a@ to @a@,
  52. -- by using the plugin rewriting functionality,
  53. -- and not the constraint solver plugin functionality.
  54. plugin :: Plugin
  55. plugin = mkPlugin don'tSolve rewriter
  56. rewriter :: [String]
  57. -> PluginDefs
  58. -> UniqFM TyCon TcPluginRewriter
  59. rewriter _args defs@( PluginDefs { add } ) =
  60. listToUFM
  61. [ ( add, rewriteAdd defs ) ]
  62. rewriteAdd :: PluginDefs -> RewriteEnv -> [ Ct ] -> [ Type ] -> TcPluginM TcPluginRewriteResult
  63. rewriteAdd ( PluginDefs { .. } ) _env givens args@[ arg1, arg2 ]
  64. | Just ( tyCon, [] ) <- splitTyConApp_maybe arg1
  65. , tyCon == zero
  66. = pure $ TcPluginRewriteTo ( mkTyFamReduction add args arg2 ) []
  67. | Just ( tyCon, [] ) <- splitTyConApp_maybe arg2
  68. , tyCon == zero
  69. = pure $ TcPluginRewriteTo ( mkTyFamReduction add args arg1 ) []
  70. rewriteAdd _ _ _ _ = pure TcPluginNoRewrite
  71. mkTyFamReduction :: TyCon -> [ Type ] -> Type -> Reduction
  72. mkTyFamReduction tyCon args res = Reduction co res
  73. where
  74. co :: Coercion
  75. co = mkUnivCo ( PluginProv "RewritePlugin" ) Nominal
  76. ( mkTyConApp tyCon args ) res