summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/users_guide/9.4.1-notes.rst5
-rw-r--r--docs/users_guide/extending_ghc.rst58
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: