diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/users_guide/9.4.1-notes.rst | 5 | ||||
-rw-r--r-- | docs/users_guide/extending_ghc.rst | 58 |
2 files changed, 63 insertions, 0 deletions
diff --git a/docs/users_guide/9.4.1-notes.rst b/docs/users_guide/9.4.1-notes.rst index aae0c065d7..ce70b8e98d 100644 --- a/docs/users_guide/9.4.1-notes.rst +++ b/docs/users_guide/9.4.1-notes.rst @@ -9,6 +9,11 @@ Compiler - New :ghc-flag:`-Wredundant-strictness-flags` that checks for strictness flags (``!``) applied to unlifted types, which are always strict. +- A new type of plugin: defaulting plugins. These plugins can propose + defaults for ambiguous variables that would otherwise cause errors + just like the built-in defaulting mechanism. + + ``base`` library ~~~~~~~~~~~~~~~~ diff --git a/docs/users_guide/extending_ghc.rst b/docs/users_guide/extending_ghc.rst index 309fa6c912..ef9b584f04 100644 --- a/docs/users_guide/extending_ghc.rst +++ b/docs/users_guide/extending_ghc.rst @@ -1275,6 +1275,64 @@ The output is as follows: | ^^^^^^^^^^^^^ +.. _defaulting-plugins: + +Defaulting plugins +~~~~~~~~~~~~~~~~~~ + +Defaulting plugins are called when ambiguous variables might otherwise cause +errors, in the same way as the built-in defaulting mechanism. + +A defaulting plugin can propose potential ways to fill an ambiguous variable +according to whatever criteria you would like. GHC will verify that those +proposals will not lead to type errors in a context that you declare. + +Defaulting plugins have a single access point in the `GHC.Tc.Types` module + +:: + + -- | A collection of candidate default types for a type variable. + data DefaultingProposal + = DefaultingProposal + { deProposalTyVar :: TcTyVar + -- ^ The type variable to default. + , deProposalCandidates :: [Type] + -- ^ Candidate types to default the type variable to. + , deProposalCts :: [Ct] + -- ^ The constraints against which defaults are checked. + } + + type DefaultingPluginResult = [DefaultingProposal] + type FillDefaulting = WantedConstraints -> TcPluginM DefaultingPluginResult + + -- | A plugin for controlling defaulting. + data DefaultingPlugin = forall s. DefaultingPlugin + { dePluginInit :: TcPluginM s + -- ^ Initialize plugin, when entering type-checker. + , dePluginRun :: s -> FillDefaulting + -- ^ Default some types + , dePluginStop :: s -> TcPluginM () + -- ^ Clean up after the plugin, when exiting the type-checker. + } + + +The plugin gets a combination of wanted constraints which can be most easily +broken down into simple wanted constraints with ``approximateWC``. The result of +running the plugin should be a ``DefaultingPluginResult``, a list of types that +should be attempted for a given type variable that is ambiguous in a given +context. GHC will check if one of the proposals is acceptable in the given +context and then default to it. The most robust context to provide is the list +of all wanted constraints that mention the variable you are defaulting. If you +leave out a constraint, the default will be accepted, and then potentially +result in a type checker error if it is incompatible with one of the constraints +you left out. This can be a useful way of forcing a default and reporting errors +to the user. + +There is an example of defaulting lifted types in the GHC test suite. In the +`testsuite/tests/plugins/` directory see `defaulting-plugin/` for the +implementation, `test-defaulting-plugin.hs` for an example of when defaulting +happens, and `test-defaulting-plugin-fail.hs` for an example of when defaults +don't fit and aren't applied. .. _plugin_recompilation: |