packages feed

ghc-tcplugin-api 0.14.0.0 → 0.15.0.0

raw patch · 4 files changed

+313/−54 lines, 4 filesdep +template-haskelldep ~ghcPVP ok

version bump matches the API change (PVP)

Dependencies added: template-haskell

Dependency ranges changed: ghc

API changes (from Hackage documentation)

- GHC.TcPlugin.API: ctev_dest :: CtEvidence -> TcEvDest
- GHC.TcPlugin.API: ctev_evar :: CtEvidence -> EvVar
- GHC.TcPlugin.API: ctev_loc :: CtEvidence -> CtLoc
- GHC.TcPlugin.API: ctev_pred :: CtEvidence -> TcPredType
- GHC.TcPlugin.API: tcPluginIO :: MonadTcPlugin m => IO a -> m a
+ GHC.TcPlugin.API: [ch_hetero_kind] :: CoercionHole -> Bool
+ GHC.TcPlugin.API: charKind :: Type
+ GHC.TcPlugin.API: className :: Class -> Name
+ GHC.TcPlugin.API: ctEvId :: HasDebugCallStack => Ct -> EvVar
+ GHC.TcPlugin.API: ctEvLoc :: CtEvidence -> CtLoc
+ GHC.TcPlugin.API: ctEvPred :: CtEvidence -> TcPredType
+ GHC.TcPlugin.API: evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvExpr
+ GHC.TcPlugin.API: evId :: EvId -> EvExpr
+ GHC.TcPlugin.API: isEqClassPred :: PredType -> Bool
+ GHC.TcPlugin.API: isEqPred :: PredType -> Bool
+ GHC.TcPlugin.API: isGiven :: CtEvidence -> Bool
+ GHC.TcPlugin.API: isWanted :: CtEvidence -> Bool
+ GHC.TcPlugin.API: lookupTHName :: forall (s :: TcPluginStage). (Monad (TcPluginM s), MonadTcPlugin (TcPluginM s)) => Name -> TcPluginM s Name
+ GHC.TcPlugin.API: natKind :: Type
+ GHC.TcPlugin.API: nonDetCmpType :: Type -> Type -> Ordering
+ GHC.TcPlugin.API: symbolKind :: Type
+ GHC.TcPlugin.API: tyConName :: TyCon -> Name
+ GHC.TcPlugin.API: typeKind :: HasDebugCallStack => Type -> Kind
+ GHC.TcPlugin.API.Internal: instance (GHC.Base.Monad (GHC.TcPlugin.API.Internal.TcPluginM s), GHC.TcPlugin.API.Internal.MonadTcPlugin (GHC.TcPlugin.API.Internal.TcPluginM s)) => Control.Monad.IO.Class.MonadIO (GHC.TcPlugin.API.Internal.TcPluginM s)
- GHC.TcPlugin.API: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> CoercionHole
+ GHC.TcPlugin.API: CoercionHole :: CoVar -> IORef (Maybe Coercion) -> Bool -> CoercionHole
- GHC.TcPlugin.API: NotFound :: [FilePath] -> Maybe Unit -> [Unit] -> [Unit] -> [(Unit, UnusableUnitReason)] -> [ModuleSuggestion] -> FindResult
+ GHC.TcPlugin.API: NotFound :: [FilePath] -> Maybe Unit -> [Unit] -> [Unit] -> [UnusableUnit] -> [ModuleSuggestion] -> FindResult
- GHC.TcPlugin.API: TcPlugin :: TcPluginM Init s -> (s -> TcPluginSolver) -> (s -> UniqFM TyCon TcPluginRewriter) -> (s -> TcPluginM Stop ()) -> TcPlugin
+ GHC.TcPlugin.API: TcPlugin :: TcPluginM 'Init s -> (s -> TcPluginSolver) -> (s -> UniqFM TyCon TcPluginRewriter) -> (s -> TcPluginM 'Stop ()) -> TcPlugin
- GHC.TcPlugin.API: [fr_unusables] :: FindResult -> [(Unit, UnusableUnitReason)]
+ GHC.TcPlugin.API: [fr_unusables] :: FindResult -> [UnusableUnit]
- GHC.TcPlugin.API: [tcPluginInit] :: TcPlugin -> TcPluginM Init s
+ GHC.TcPlugin.API: [tcPluginInit] :: TcPlugin -> TcPluginM 'Init s
- GHC.TcPlugin.API: [tcPluginStop] :: TcPlugin -> s -> TcPluginM Stop ()
+ GHC.TcPlugin.API: [tcPluginStop] :: TcPlugin -> s -> TcPluginM 'Stop ()
- GHC.TcPlugin.API: askDeriveds :: TcPluginM Solve [Ct]
+ GHC.TcPlugin.API: askDeriveds :: TcPluginM 'Solve [Ct]
- GHC.TcPlugin.API: askEvBinds :: TcPluginM Solve EvBindsVar
+ GHC.TcPlugin.API: askEvBinds :: TcPluginM 'Solve EvBindsVar
- GHC.TcPlugin.API: askRewriteEnv :: TcPluginM Rewrite RewriteEnv
+ GHC.TcPlugin.API: askRewriteEnv :: TcPluginM 'Rewrite RewriteEnv
- GHC.TcPlugin.API: class (Monad m, (forall x y. Coercible x y => Coercible (m x) (m y))) => MonadTcPlugin (m :: Type -> Type)
+ GHC.TcPlugin.API: class (Monad m, forall x y. Coercible x y => Coercible m x m y) => MonadTcPlugin (m :: Type -> Type)
- GHC.TcPlugin.API: class MonadTcPlugin m => MonadTcPluginWork m
+ GHC.TcPlugin.API: class MonadTcPlugin m => MonadTcPluginWork (m :: Type -> Type)
- GHC.TcPlugin.API: class () => Outputable a
+ GHC.TcPlugin.API: class Outputable a
- GHC.TcPlugin.API: data () => Boxity
+ GHC.TcPlugin.API: data Boxity
- GHC.TcPlugin.API: data () => Class
+ GHC.TcPlugin.API: data Class
- GHC.TcPlugin.API: data () => Coercion
+ GHC.TcPlugin.API: data Coercion
- GHC.TcPlugin.API: data () => CoercionHole
+ GHC.TcPlugin.API: data CoercionHole
- GHC.TcPlugin.API: data () => Ct
+ GHC.TcPlugin.API: data Ct
- GHC.TcPlugin.API: data () => CtEvidence
+ GHC.TcPlugin.API: data CtEvidence
- GHC.TcPlugin.API: data () => CtFlavour
+ GHC.TcPlugin.API: data CtFlavour
- GHC.TcPlugin.API: data () => CtLoc
+ GHC.TcPlugin.API: data CtLoc
- GHC.TcPlugin.API: data () => CtOrigin
+ GHC.TcPlugin.API: data CtOrigin
- GHC.TcPlugin.API: data () => DataCon
+ GHC.TcPlugin.API: data DataCon
- GHC.TcPlugin.API: data () => EqRel
+ GHC.TcPlugin.API: data EqRel
- GHC.TcPlugin.API: data () => EvBind
+ GHC.TcPlugin.API: data EvBind
- GHC.TcPlugin.API: data () => EvBindsVar
+ GHC.TcPlugin.API: data EvBindsVar
- GHC.TcPlugin.API: data () => EvTerm
+ GHC.TcPlugin.API: data EvTerm
- GHC.TcPlugin.API: data () => Expr b
+ GHC.TcPlugin.API: data Expr b
- GHC.TcPlugin.API: data () => FamInstEnv
+ GHC.TcPlugin.API: data FamInstEnv
- GHC.TcPlugin.API: data () => FastString
+ GHC.TcPlugin.API: data FastString
- GHC.TcPlugin.API: data () => FindResult
+ GHC.TcPlugin.API: data FindResult
- GHC.TcPlugin.API: data () => GenLocated l e
+ GHC.TcPlugin.API: data GenLocated l e
- GHC.TcPlugin.API: data () => InertSet
+ GHC.TcPlugin.API: data InertSet
- GHC.TcPlugin.API: data () => InstEnvs
+ GHC.TcPlugin.API: data InstEnvs
- GHC.TcPlugin.API: data () => MetaDetails
+ GHC.TcPlugin.API: data MetaDetails
- GHC.TcPlugin.API: data () => MetaInfo
+ GHC.TcPlugin.API: data MetaInfo
- GHC.TcPlugin.API: data () => ModuleName
+ GHC.TcPlugin.API: data ModuleName
- GHC.TcPlugin.API: data () => Name
+ GHC.TcPlugin.API: data Name
- GHC.TcPlugin.API: data () => OccName
+ GHC.TcPlugin.API: data OccName
- GHC.TcPlugin.API: data () => PkgQual
+ GHC.TcPlugin.API: data PkgQual
- GHC.TcPlugin.API: data () => Pred
+ GHC.TcPlugin.API: data Pred
- GHC.TcPlugin.API: data () => PromotionFlag
+ GHC.TcPlugin.API: data PromotionFlag
- GHC.TcPlugin.API: data () => QCInst
+ GHC.TcPlugin.API: data QCInst
- GHC.TcPlugin.API: data () => Reduction
+ GHC.TcPlugin.API: data Reduction
- GHC.TcPlugin.API: data () => RewriteEnv
+ GHC.TcPlugin.API: data RewriteEnv
- GHC.TcPlugin.API: data () => Role
+ GHC.TcPlugin.API: data Role
- GHC.TcPlugin.API: data () => SDoc
+ GHC.TcPlugin.API: data SDoc
- GHC.TcPlugin.API: data () => TcEvDest
+ GHC.TcPlugin.API: data TcEvDest
- GHC.TcPlugin.API: data () => TcGblEnv
+ GHC.TcPlugin.API: data TcGblEnv
- GHC.TcPlugin.API: data () => TcLclEnv
+ GHC.TcPlugin.API: data TcLclEnv
- GHC.TcPlugin.API: data () => TcLevel
+ GHC.TcPlugin.API: data TcLevel
- GHC.TcPlugin.API: data () => TcPluginRewriteResult
+ GHC.TcPlugin.API: data TcPluginRewriteResult
- GHC.TcPlugin.API: data () => TcPluginSolveResult
+ GHC.TcPlugin.API: data TcPluginSolveResult
- GHC.TcPlugin.API: data () => TcS a
+ GHC.TcPlugin.API: data TcS a
- GHC.TcPlugin.API: data () => TcTyThing
+ GHC.TcPlugin.API: data TcTyThing
- GHC.TcPlugin.API: data () => TupleSort
+ GHC.TcPlugin.API: data TupleSort
- GHC.TcPlugin.API: data () => TyCon
+ GHC.TcPlugin.API: data TyCon
- GHC.TcPlugin.API: data () => TyThing
+ GHC.TcPlugin.API: data TyThing
- GHC.TcPlugin.API: data () => Type
+ GHC.TcPlugin.API: data Type
- GHC.TcPlugin.API: data () => UniqDFM key ele
+ GHC.TcPlugin.API: data UniqDFM key ele
- GHC.TcPlugin.API: data () => UniqFM key ele
+ GHC.TcPlugin.API: data UniqFM key ele
- GHC.TcPlugin.API: data () => Unique
+ GHC.TcPlugin.API: data Unique
- GHC.TcPlugin.API: data () => UnitId
+ GHC.TcPlugin.API: data UnitId
- GHC.TcPlugin.API: data () => UnivCoProvenance
+ GHC.TcPlugin.API: data UnivCoProvenance
- GHC.TcPlugin.API: evCast :: EvExpr -> TcCoercion -> EvTerm
+ GHC.TcPlugin.API: evCast :: EvExpr -> Coercion -> EvExpr
- GHC.TcPlugin.API: evDataConApp :: DataCon -> [Type] -> [EvExpr] -> EvTerm
+ GHC.TcPlugin.API: evDataConApp :: DataCon -> [Type] -> [EvExpr] -> EvExpr
- GHC.TcPlugin.API: newCoercionHole :: PredType -> TcPluginM Solve CoercionHole
+ GHC.TcPlugin.API: newCoercionHole :: PredType -> TcPluginM 'Solve CoercionHole
- GHC.TcPlugin.API: newEvVar :: PredType -> TcPluginM Solve EvVar
+ GHC.TcPlugin.API: newEvVar :: PredType -> TcPluginM 'Solve EvVar
- GHC.TcPlugin.API: newGiven :: CtLoc -> PredType -> EvExpr -> TcPluginM Solve CtEvidence
+ GHC.TcPlugin.API: newGiven :: CtLoc -> PredType -> EvTerm -> TcPluginM 'Solve CtEvidence
- GHC.TcPlugin.API: readTcRef :: TcRef a -> TcRnIf gbl lcl a
+ GHC.TcPlugin.API: readTcRef :: MonadIO m => TcRef a -> m a
- GHC.TcPlugin.API: setCtLocRewriteM :: TcPluginM Rewrite a -> TcPluginM Rewrite a
+ GHC.TcPlugin.API: setCtLocRewriteM :: TcPluginM 'Rewrite a -> TcPluginM 'Rewrite a
- GHC.TcPlugin.API: setEvBind :: EvBind -> TcPluginM Solve ()
+ GHC.TcPlugin.API: setEvBind :: EvBind -> TcPluginM 'Solve ()
- GHC.TcPlugin.API: type TcPluginRewriter = -- | Givens [Ct] -> -- | Type family arguments (saturated) [Type] -> TcPluginM Rewrite TcPluginRewriteResult
+ GHC.TcPlugin.API: type TcPluginRewriter = [Ct] -> [Type] -> TcPluginM 'Rewrite TcPluginRewriteResult
- GHC.TcPlugin.API: type TcPluginSolver = -- | Givens [Ct] -> -- | Wanteds [Ct] -> TcPluginM Solve TcPluginSolveResult
+ GHC.TcPlugin.API: type TcPluginSolver = [Ct] -> [Ct] -> TcPluginM 'Solve TcPluginSolveResult
- GHC.TcPlugin.API: writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> TcM ()
+ GHC.TcPlugin.API: writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> ZonkM ()
- GHC.TcPlugin.API: writeTcRef :: TcRef a -> a -> TcRnIf gbl lcl ()
+ GHC.TcPlugin.API: writeTcRef :: MonadIO m => TcRef a -> a -> m ()
- GHC.TcPlugin.API.Internal: TcPlugin :: TcPluginM Init s -> (s -> TcPluginSolver) -> (s -> UniqFM TyCon TcPluginRewriter) -> (s -> TcPluginM Stop ()) -> TcPlugin
+ GHC.TcPlugin.API.Internal: TcPlugin :: TcPluginM 'Init s -> (s -> TcPluginSolver) -> (s -> UniqFM TyCon TcPluginRewriter) -> (s -> TcPluginM 'Stop ()) -> TcPlugin
- GHC.TcPlugin.API.Internal: [tcPluginInit] :: TcPlugin -> TcPluginM Init s
+ GHC.TcPlugin.API.Internal: [tcPluginInit] :: TcPlugin -> TcPluginM 'Init s
- GHC.TcPlugin.API.Internal: [tcPluginStop] :: TcPlugin -> s -> TcPluginM Stop ()
+ GHC.TcPlugin.API.Internal: [tcPluginStop] :: TcPlugin -> s -> TcPluginM 'Stop ()
- GHC.TcPlugin.API.Internal: askDeriveds :: TcPluginM Solve [Ct]
+ GHC.TcPlugin.API.Internal: askDeriveds :: TcPluginM 'Solve [Ct]
- GHC.TcPlugin.API.Internal: askEvBinds :: TcPluginM Solve EvBindsVar
+ GHC.TcPlugin.API.Internal: askEvBinds :: TcPluginM 'Solve EvBindsVar
- GHC.TcPlugin.API.Internal: askRewriteEnv :: TcPluginM Rewrite RewriteEnv
+ GHC.TcPlugin.API.Internal: askRewriteEnv :: TcPluginM 'Rewrite RewriteEnv
- GHC.TcPlugin.API.Internal: class (Monad m, (forall x y. Coercible x y => Coercible (m x) (m y))) => MonadTcPlugin (m :: Type -> Type)
+ GHC.TcPlugin.API.Internal: class (Monad m, forall x y. Coercible x y => Coercible m x m y) => MonadTcPlugin (m :: Type -> Type)
- GHC.TcPlugin.API.Internal: class MonadTcPlugin m => MonadTcPluginWork m
+ GHC.TcPlugin.API.Internal: class MonadTcPlugin m => MonadTcPluginWork (m :: Type -> Type)
- GHC.TcPlugin.API.Internal: type TcPluginRewriter = -- | Givens [Ct] -> -- | Type family arguments (saturated) [Type] -> TcPluginM Rewrite TcPluginRewriteResult
+ GHC.TcPlugin.API.Internal: type TcPluginRewriter = [Ct] -> [Type] -> TcPluginM 'Rewrite TcPluginRewriteResult
- GHC.TcPlugin.API.Internal: type TcPluginSolver = -- | Givens [Ct] -> -- | Wanteds [Ct] -> TcPluginM Solve TcPluginSolveResult
+ GHC.TcPlugin.API.Internal: type TcPluginSolver = [Ct] -> [Ct] -> TcPluginM 'Solve TcPluginSolveResult
- GHC.TcPlugin.API.Internal: unsafeWithRunInTcM :: MonadTcPlugin m => ((forall a. m a -> TcM a) -> TcM b) -> m b
+ GHC.TcPlugin.API.Internal: unsafeWithRunInTcM :: MonadTcPlugin m => ((forall a. () => m a -> TcM a) -> TcM b) -> m b
- GHC.TcPlugin.API.Names: Qualified :: String -> ModuleName -> PkgQual -> QualifiedName (thing :: Type)
+ GHC.TcPlugin.API.Names: Qualified :: String -> ModuleName -> PkgQual -> QualifiedName thing
- GHC.TcPlugin.API.Names: [module'] :: QualifiedName (thing :: Type) -> ModuleName
+ GHC.TcPlugin.API.Names: [module'] :: QualifiedName thing -> ModuleName
- GHC.TcPlugin.API.Names: [name] :: QualifiedName (thing :: Type) -> String
+ GHC.TcPlugin.API.Names: [name] :: QualifiedName thing -> String
- GHC.TcPlugin.API.Names: [package] :: QualifiedName (thing :: Type) -> PkgQual
+ GHC.TcPlugin.API.Names: [package] :: QualifiedName thing -> PkgQual
- GHC.TcPlugin.API.Names: data Promoted (thing :: k) :: Type
+ GHC.TcPlugin.API.Names: data Promoted (thing :: k)
- GHC.TcPlugin.API.Names: data QualifiedName (thing :: Type)
+ GHC.TcPlugin.API.Names: data QualifiedName thing
- GHC.TcPlugin.API.Names: lookup :: (Lookupable a, MonadTcPlugin m) => Name -> m (Wear Resolved a)
+ GHC.TcPlugin.API.Names: lookup :: (Lookupable a, MonadTcPlugin m) => Name -> m (Wear 'Resolved a)
- GHC.TcPlugin.API.Names: newtype () => Generically1 (f :: k -> Type) (a :: k)
+ GHC.TcPlugin.API.Names: newtype Generically1 (f :: k -> Type) (a :: k)
- GHC.TcPlugin.API.Names: resolveNames :: (MonadTcPlugin m, ResolveNames f) => f Named -> m (f Resolved)
+ GHC.TcPlugin.API.Names: resolveNames :: (MonadTcPlugin m, ResolveNames f) => f 'Named -> m (f 'Resolved)
- GHC.TcPlugin.API.Names: type family Wear (n :: NameResolution) (thing :: k) :: Type
+ GHC.TcPlugin.API.Names: type family Wear (n :: NameResolution) (thing :: k)

Files

changelog.md view
@@ -1,3 +1,38 @@+# Version 0.15.0.0 (2025-06-03)
+
+- Remove `tcPluginIO` in favour of new `MonadIO` instance.  
+  To migrate, use `liftIO` instead of `tcPluginIO`.
+
+- Add `lookupTHName` function, which allows looking up Template Haskell names
+  in typechecker plugins. Useful in conjunction with `TemplateHaskellQuotes`.
+
+- Helper functions to construct evidence terms have been adjusted to return
+  values of type `EvExpr`, rather than `EvTerm`. This makes the functions more
+  composable, and allows typechecker plugin to provide evidence for quantified
+  constraints more easily.
+
+  Affected functions: `evDFunApp`, `evDataConApp`, `evCast`.
+
+  To migrate, you will need to manually wrap evidence terms with the
+  `EvExpr` constructor in places that expect an `EvTerm`.
+
+- Added `natKind`, `symbolKind` and `charKind` for the kinds of type-level
+  `Nat`, `Symbol` and `Char`.
+
+- Added several re-exports from the `ghc` library:
+  - `isGiven` & `isWanted`.
+  - `ctEvPred`, `ctEvId`, `ctEvExpr` and `ctEvLoc`.
+  - `className` & `tyConName`.
+  - `isEqPred` (unboxed equality) and `isEqClassPred` (boxed equality).
+  - `evId` & `ctEvId`.
+  - `typeKind`.
+  - `nonDetCmpType`.
+
+- Removed re-exports of `ctev_pred`, `ctev_loc`, `ctev_evar`, and `ctev_dest`.
+
+  Migration: use `ctEvPred` instead of `ctev_pred` and `ctEvLoc` instead of `ctev_loc`.
+  Uses of `ctev_evar` and `ctev_dest` should be covered by `ctEvEvId` and/or
+  `ctEvExpr`.
 
 # Version 0.14.0.0 (2024-11-28)
 
ghc-tcplugin-api.cabal view
@@ -1,12 +1,12 @@ cabal-version:  3.0
 name:           ghc-tcplugin-api
-version:        0.14.0.0
+version:        0.15.0.0
 synopsis:       An API for type-checker plugins.
 license:        BSD-3-Clause
 build-type:     Simple
 author:         Sam Derbyshire
 maintainer:     Sam Derbyshire
-copyright:      2021-2024 Sam Derbyshire
+copyright:      2021-2025 Sam Derbyshire
 homepage:       https://github.com/sheaf/ghc-tcplugin-api
 category:       Type System, GHC, Plugin
 description:
@@ -37,9 +37,11 @@     containers
       >= 0.6    && < 0.8,
     ghc
-      >= 8.8    && < 9.14,
+      >= 8.8    && < 9.16,
     transformers
       >= 0.5    && < 0.7,
+    template-haskell
+      >= 2.15   && < 2.25,
 
   default-language:
     Haskell2010
@@ -72,6 +74,11 @@     , GHC.Types.Unique.DSet
     , GHC.Utils.Outputable
 
+  if impl(ghc >= 9.13.0)
+    -- Don't warn on exports of the form "pattern ClassPred".
+    -- We can migrate to using "data" when that becomes necessary.
+    ghc-options: -Wno-pattern-namespace-specifier
+
   if impl(ghc >= 9.3.0)
     cpp-options: -DHAS_REWRITING
   else
@@ -110,6 +117,8 @@         , DynFlags   as GHC.Driver.Session
         , HscTypes   as GHC.Driver.Types
 
+        , IfaceEnv   as GHC.Iface.Env
+
         , GhcPlugins as GHC.Plugins
 
         , TcPluginM  as GHC.Tc.Plugin
@@ -125,6 +134,7 @@         , Literal    as GHC.Types.Literal
         , Name       as GHC.Types.Name
         , OccName    as GHC.Types.Name.Occurrence
+        , RdrName    as GHC.Types.Name.Reader
         , SrcLoc     as GHC.Types.SrcLoc
         , Unique     as GHC.Types.Unique
         , UniqDFM    as GHC.Types.Unique.DFM
@@ -152,6 +162,7 @@           ( Predicate  as GHC.Core.Predicate
           , Constraint as GHC.Tc.Types.Constraint
           , TcOrigin   as GHC.Tc.Types.Origin
+          , GHC.ThToHs as GHC.ThToHs
           )
 
     else
@@ -161,4 +172,5 @@           ( Type      as GHC.Core.Predicate
           , TcRnTypes as GHC.Tc.Types.Constraint
           , TcRnTypes as GHC.Tc.Types.Origin
+          , Convert   as GHC.ThToHs
           )
src/GHC/TcPlugin/API.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE CPP #-}
+
+{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -64,7 +67,6 @@     -- typeclass providing overloading (for operations that work in all stages).
   , TcPluginStage(..), MonadTcPlugin
   , TcPluginM
-  , tcPluginIO
 
     -- *** Emitting new work, and throwing type-errors
 
@@ -80,10 +82,23 @@     -- | Name resolution is usually the first step in writing a type-checking plugin:
     -- plugins need to look up the names of the objects they want to manipulate.
     --
-    -- For instance, to lookup the type family @MyFam@ in module @MyModule@ in package @my-pkg@:
+    -- The most convenient way to look up a Name is to bring the name into scope
+    -- in the module defining the plugin, and use @TemplateHaskellQuotes@
+    -- in conjunction with the 'lookupTHName' function.
     --
-    -- > lookupMyModule :: MonadTcPlugin m => m Module
-    -- > lookupMyModule = do
+    -- > import Data.Maybe
+    -- >
+    -- > lookupMaybeTyCon :: MonadTcPluginM m => m TyCon
+    -- > lookupMaybeTyCon = lookupTHName ''Maybe >>= tcLookupTyCon
+    --
+    -- This is recommended over manually looking up the package and module
+    -- name, because the manual method does not robustly deal with re-exports;
+    -- one must specify the exact package/module which defines the identifier.
+    -- For instance, to manually lookup the type family @MyFam@ in module
+    -- @MyModule@ in package @my-pkg@:
+    --
+    -- > lookupMyFam :: MonadTcPluginM m => m Name
+    -- > lookupMyFam = do
     -- >    let modlName = mkModuleName "MyModule"
     -- >        pkgName  = Just $ fsLit "my-pkg"
     -- >    pkgQual    <- resolveImport      modlName pkgName
@@ -99,31 +114,38 @@     -- to the other stages: the plugin initialisation is called only once in each module
     -- that the plugin is used, whereas the solver and rewriter are usually called repeatedly.
 
-    -- ** Packages and modules
+    -- ** Name resolution: TH method
 
+    -- | Look up a Name from a Template Haskell Name (e.g. a Name constructed
+    -- using TemplateHaskellQuotes).
+  , lookupTHName
+
+    -- ** Name resolution: manual method
+    -- *** Packages and modules
+
     -- | Use these functions to lookup a module,
     -- from the current package or imported packages.
   , findImportedModule, resolveImport, fsLit, unpackFS, mkModuleName
   , unitIdFS, stringToUnitId, pkgQualToPkgName
   , Module, ModuleName, FindResult(..), UnitId, PkgQual
 
-    -- ** Names
+    -- *** Names
 
-    -- *** Occurence names
+    -- **** Occurence names
 
     -- | The most basic type of name is the 'OccName', which is a
     -- simple textual name within a namespace (e.g. the class namespace),
     -- without any disambiguation (no module qualifier, etc).
   , mkVarOcc, mkDataOcc, mkTyVarOcc, mkTcOcc, mkClsOcc
 
-    -- *** Names
+    -- **** Names
 
     -- | After having looked up the 'Module', we can obtain the full 'Name'
     -- referred to by an 'OccName'. This is fully unambiguous, as it
     -- contains a 'Unique' identifier for the name.
   , lookupOrig
 
-    -- *** 'TyCon', 'Class', 'DataCon', etc
+    -- ** Name resolution: resolving the Name to a 'TyCon', 'Class', 'DataCon', etc
 
     -- | Finally, we can obtain the actual objects we're interested in handling,
     -- such as classes, type families, data constructors... by looking them up
@@ -244,8 +266,12 @@   , readTcRef, writeTcRef
 
     -- | == Some further functions for inspecting constraints
-  , eqType
+  , eqType, nonDetCmpType
   , ctLoc, ctEvidence, ctFlavour, ctEqRel, ctOrigin
+  , ctEvPred, ctEvId, ctEvExpr, ctEvLoc
+  , isGiven, isWanted
+  , isEqPred, isEqClassPred
+  , className, tyConName
 
     -- ** Constraint evidence
 
@@ -282,13 +308,11 @@     -- by combining evidence that is already available.
 
   , mkPluginUnivEvTerm
-  , evDataConApp
+  , evDFunApp, evDataConApp
   , newEvVar, setEvBind
-  , evCoercion, evCast
-  , ctEvExpr
+  , evId, evCoercion, evCast
   , askEvBinds, lookupEvBind, eb_lhs, eb_rhs
   , newName, mkLocalId, mkTyVar
-  , ctev_pred, ctev_evar, ctev_loc, ctev_dest
 
     -- *** Class dictionaries
 
@@ -395,6 +419,7 @@     -- ** Type literals (natural numbers, type-level strings)
   , mkNumLitTy, isNumLitTy
   , mkStrLitTy, isStrLitTy
+  , natKind, symbolKind, charKind
 
     -- ** Creating and decomposing applications
   , mkTyConTy, mkTyConApp, mkAppTy, mkAppTys
@@ -408,6 +433,8 @@   , mkForAllTy, mkForAllTys
   , mkPiTy, mkPiTys
 
+    -- ** Kinds
+  , typeKind
 
 #if MIN_VERSION_ghc(9,0,0)
   , Mult
@@ -503,6 +530,19 @@ -- ghc
 import GHC
   ( TyThing(..) )
+import GHC.Builtin.Names
+ ( hasKey
+ , eqPrimTyConKey, eqReprPrimTyConKey
+ , heqTyConKey, eqTyConKey, coercibleTyConKey
+ )
+import GHC.Builtin.Types
+  ( typeSymbolKind, charTy
+#if MIN_VERSION_ghc(9,1,0)
+  , naturalTy
+#else
+  , typeNatKind
+#endif
+  )
 #if !MIN_VERSION_ghc(9,0,0)
 import GHC.Builtin.Types
   ( intDataCon )
@@ -510,12 +550,12 @@   ( intPrimTy )
 #endif
 import GHC.Core
-  ( CoreBndr, CoreExpr, Expr(..) )
+  ( CoreBndr, CoreExpr, Expr(..), mkTyApps, mkApps )
 import GHC.Core.Class
   ( Class(..), FunDep )
 import GHC.Core.Coercion
   ( mkReflCo, mkSymCo, mkTransCo
-  , mkUnivCo
+  , mkUnivCo, isReflCo
 #if !MIN_VERSION_ghc(9,13,0) && MIN_VERSION_ghc(8,10,0)
   , mkPrimEqPredRole
 #endif
@@ -524,7 +564,7 @@   ( Role(..) )
 import GHC.Core.DataCon
   ( DataCon
-  , classDataCon, promoteDataCon
+  , classDataCon, promoteDataCon, dataConWrapId
   )
 import GHC.Core.FamInstEnv
   ( FamInstEnv )
@@ -552,7 +592,7 @@   ( Reduction(..) )
 #endif
 import GHC.Core.TyCon
-  ( TyCon(..) )
+  ( TyCon(..), tyConClass_maybe )
 #if MIN_VERSION_ghc(9,6,0)
 import GHC.Core.TyCo.Compare
   ( eqType )
@@ -589,6 +629,7 @@   , mkAppTy, mkAppTys, isTyVarTy, getTyVar_maybe
   , mkCoercionTy, isCoercionTy, isCoercionTy_maybe
   , mkNumLitTy, isNumLitTy, mkStrLitTy, isStrLitTy
+  , typeKind
 #if !MIN_VERSION_ghc(9,6,0)
   , eqType
 #endif
@@ -600,6 +641,28 @@   )
 import GHC.Data.FastString
   ( FastString, fsLit, unpackFS )
+#if MIN_VERSION_ghc(9,5,0)
+import GHC.Plugins
+  ( thNameToGhcNameIO )
+#else
+import Data.Maybe
+  ( listToMaybe )
+#if MIN_VERSION_ghc(9,3,0)
+import GHC.Iface.Env
+  ( lookupNameCache )
+#else
+import GHC.Iface.Env
+  ( lookupOrigIO )
+#endif
+import GHC.ThToHs
+  ( thRdrNameGuesses )
+import GHC.Types.Name
+  ( isExternalName )
+import GHC.Types.Name.Reader
+  ( isExact_maybe, isOrig_maybe )
+import GHC.Utils.Monad
+  ( mapMaybeM )
+#endif
 import qualified GHC.Tc.Plugin
   as GHC
 #if MIN_VERSION_ghc(9,4,0)
@@ -628,21 +691,27 @@ #if MIN_VERSION_ghc(9,11,0)
 import GHC.Tc.Types.CtLoc
   ( CtLoc(..), bumpCtLocDepth )
+#else
+import GHC.Tc.Types.Constraint
+  ( CtLoc(..), bumpCtLocDepth )
 #endif
+#if MIN_VERSION_ghc(9,13,0)
 import GHC.Tc.Types.Constraint
+  ( GivenCtEvidence(..) )
+#endif
+import GHC.Tc.Types.Constraint
   ( Ct(..), CtEvidence(..), CtFlavour(..)
   , QCInst(..), TcEvDest(..)
   , ctPred, ctLoc, ctEvidence, ctEvExpr
   , ctEvCoercion
   , ctFlavour, ctEqRel, ctOrigin
-  , mkNonCanonical
-#if !MIN_VERSION_ghc(9,11,0)
-  , CtLoc(..), bumpCtLocDepth
-#endif
+  , ctEvFlavour, ctEvPred, ctEvLoc
+  , mkNonCanonical, ctEvId
   )
 import GHC.Tc.Types.Evidence
   ( EvBind(..), EvTerm(..), EvExpr, EvBindsVar(..)
-  , evCoercion, evCast, lookupEvBind, evDataConApp
+  , evCoercion, lookupEvBind
+  , mkGivenEvBind, evId
   )
 import GHC.Tc.Types.Origin
   ( CtOrigin(..) )
@@ -654,6 +723,7 @@ import GHC.Tc.Utils.TcType
   ( TcType, TcLevel, MetaDetails, MetaInfo
   , isSkolemTyVar, isMetaTyVar
+  , nonDetCmpType
   )
 import GHC.Tc.Utils.TcMType
   ( isFilledMetaTyVar_maybe, writeMetaTyVar )
@@ -673,15 +743,20 @@   ( OccName(..)
   , mkVarOcc, mkDataOcc, mkTyVarOcc, mkTcOcc, mkClsOcc
   )
-#if MIN_VERSION_ghc(9,3,0)
-import GHC
+#if MIN_VERSION_ghc(9,1,0)
+import GHC.Driver.Env.Types
   ( HscEnv )
+#else
+import GHC.Driver.Types
+  ( HscEnv )
+#endif
+#if MIN_VERSION_ghc(9,3,0)
+import GHC.Driver.Env.Types
+  ( hsc_unit_env, hsc_NC )
 import GHC.Types.PkgQual
   ( PkgQual(..) )
 import GHC.Rename.Names
   ( renamePkgQual )
-import GHC.Driver.Env
-  ( hsc_unit_env )
 import GHC.Unit.Module
   ( unitIdString )
 #elif MIN_VERSION_ghc(9,1,0)
@@ -707,17 +782,16 @@   ( UniqDFM, lookupUDFM, lookupUDFM_Directly, elemUDFM )
 import GHC.Types.Var
   ( TyVar, CoVar, TcTyVar, EvVar
-  , mkTyVar
+  , mkTyVar, DFunId
   )
 import GHC.Utils.Outputable
-  ( Outputable(..), SDoc
-#if !MIN_VERSION_ghc(9,2,0)
-  , panic, pprPanic
-#endif
-  )
+  ( Outputable(..), SDoc, text )
 #if MIN_VERSION_ghc(9,2,0)
 import GHC.Utils.Panic
   ( panic, pprPanic )
+#else
+import GHC.Utils.Outputable
+  ( panic, pprPanic )
 #endif
 #if MIN_VERSION_ghc(9,2,0)
 import GHC.Unit.Finder
@@ -742,22 +816,21 @@   ( HasDebugCallStack )
 #endif
 
--- transformers
-import Control.Monad.IO.Class
-  ( MonadIO ( liftIO ) )
-
 -- ghc-tcplugin-api
 import GHC.TcPlugin.API.Internal
 #ifndef HAS_REWRITING
 import GHC.TcPlugin.API.Internal.Shim
 #endif
 
---------------------------------------------------------------------------------
+-- template-haskell
+import qualified Language.Haskell.TH as TH
 
--- | Run an 'IO' computation within the plugin.
-tcPluginIO :: MonadTcPlugin m => IO a -> m a
-tcPluginIO = unsafeLiftTcM . liftIO
+-- transformers
+import Control.Monad.IO.Class
+  ( MonadIO ( liftIO ) )
 
+--------------------------------------------------------------------------------
+
 -- | Output some debugging information within the plugin.
 tcPluginTrace :: MonadTcPlugin m
               => String -- ^ Text at the top of the debug message.
@@ -887,10 +960,8 @@ 
 --------------------------------------------------------------------------------
 
-#if MIN_VERSION_ghc(9,3,0)
 getTopEnv :: MonadTcPlugin m => m HscEnv
 getTopEnv = liftTcPluginM GHC.getTopEnv
-#endif
 
 -- | Obtain the current global and local type-checking environments.
 getEnvs :: MonadTcPlugin m => m ( TcGblEnv, TcLclEnv )
@@ -950,6 +1021,18 @@ 
 --------------------------------------------------------------------------------
 
+-- | Is this a "Given" constraint?
+isGiven :: CtEvidence -> Bool
+isGiven ev = case ctEvFlavour ev of
+  Given {} -> True
+  _ -> False
+
+-- | Is this a "Wanted" constraint?
+isWanted :: CtEvidence -> Bool
+isWanted = not . isGiven
+
+--------------------------------------------------------------------------------
+
 -- | Create a new Wanted constraint.
 --
 -- Requires a location (so that error messages can say where the constraint came from,
@@ -967,15 +1050,19 @@ -- | Create a new Given constraint.
 --
 -- Unlike 'newWanted', we need to supply evidence for this constraint.
-newGiven :: CtLoc -> PredType -> EvExpr -> TcPluginM Solve CtEvidence
+newGiven :: CtLoc -> PredType -> EvTerm -> TcPluginM Solve CtEvidence
 newGiven loc pty evtm = do
-#if HAS_REWRITING
-  tc_evbinds <- askEvBinds
-  liftTcPluginM $ GHC.newGiven tc_evbinds loc pty evtm
-#else
-  liftTcPluginM $ GHC.newGiven loc pty evtm
+   new_ev <- newEvVar pty
+   setEvBind $ mkGivenEvBind new_ev evtm
+   return $
+      CtGiven
+#if MIN_VERSION_ghc(9,13,0)
+        $ GivenCt
 #endif
-
+        { ctev_pred = pty
+        , ctev_evar = new_ev
+        , ctev_loc = loc
+        }
 
 -- | Obtain the 'CtLoc' from a 'RewriteEnv'.
 --
@@ -1078,7 +1165,9 @@   -> TcType     -- ^ The type that the type family application reduces to
   -> Reduction
 mkTyFamAppReduction str role deps tc args ty =
-  Reduction ( mkPluginUnivCo str role deps ( mkTyConApp tc args ) ty ) ty
+  Reduction
+    ( mkPluginUnivCo str role deps ( mkTyConApp tc args ) ty )
+    ty
 
 --------------------------------------------------------------------------------
 
@@ -1145,6 +1234,123 @@ 
 setInertSet :: InertSet -> TcS ()
 setInertSet = setTcSInerts
+#endif
+
+--------------------------------------------------------------------------------
+
+-- | Resolve a @template-haskell@ 'TH.Name' to a GHC 'Name'.
+--
+-- Especially useful in conjunction with @TemplateHaskellQuotes@, e.g. to
+-- look up the 'Name' of the @Maybe@ type constructor, you can do:
+--
+--  > lookupName ''Maybe
+--
+-- @since 0.15.0.0
+lookupTHName :: ( Monad (TcPluginM s), MonadTcPlugin (TcPluginM s) )
+             => TH.Name -> TcPluginM s Name
+lookupTHName thNm = do
+  hscEnv <- getTopEnv
+  mbNm <-
+    liftIO $
+      thNameToGhcNameIO
+#if MIN_VERSION_ghc(9,6,0)
+        (hsc_NC hscEnv)
+#else
+        hscEnv
+#endif
+        thNm
+  case mbNm of
+    Just nm ->
+      return nm
+    Nothing ->
+      pprPanic "lookupTHName: lookup failed" (text $ show thNm)
+
+--------------------------------------------------------------------------------
+
+-- | Apply an instance dictionary function to type and value arguments.
+--
+-- NB: different from @evDFunApp@ defined in GHC, as this function returns
+-- an @EvExpr@ rather than an @EvTerm@.
+evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvExpr
+evDFunApp df tys ets = Var df `mkTyApps` tys `mkApps` ets
+
+-- | Apply a data constructor to type and value arguments.
+--
+-- NB: different from @evDataConApp@ defined in GHC, as this function returns
+-- an @EvExpr@ rather than an @EvTerm@.
+evDataConApp :: DataCon -> [Type] -> [EvExpr] -> EvExpr
+evDataConApp dc tys ets = evDFunApp (dataConWrapId dc) tys ets
+
+-- | Cast an evidence expression by a coercion.
+--
+-- NB: different from @evCast@ defined in GHC, as this function returns
+-- an @EvExpr@ rather than an @EvTerm@.
+evCast :: EvExpr -> Coercion -> EvExpr
+evCast et co | isReflCo co = et
+             | otherwise   = Cast et co
+
+--------------------------------------------------------------------------------
+
+natKind, symbolKind, charKind :: Type
+natKind =
+#if MIN_VERSION_ghc(9,1,0)
+  naturalTy
+#else
+  typeNatKind
+#endif
+symbolKind = typeSymbolKind
+charKind = charTy
+
+--------------------------------------------------------------------------------
+
+-- | Is this a primitive (unboxed) equality type, i.e. one of:
+--
+--  - @~#@ (heterogeneous nominal unboxed equality),
+--  - @~R#@ (heterogeneous representational unboxed equality).
+--
+-- NB: returns @False@ for **boxed** equalities such as @(~)@, @(~~)@ and @Coercible@.
+-- If you want to detect those, use 'isEqClassPred'.
+isEqPred :: PredType -> Bool
+isEqPred pty
+  | Just tc <- tyConAppTyCon_maybe pty
+  = tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey
+  | otherwise
+  = False
+
+-- | Is this a boxed equality type, i.e. one of:
+--
+--  - @(~)@ (homogeneous nominal boxed equality),
+--  - @(~~)@ (heterogeneous nominal boxed equality),
+--  - @Coercible@ (homogeneous boxed representational equality).
+isEqClassPred :: PredType -> Bool
+isEqClassPred pty
+  | Just tc <- tyConAppTyCon_maybe pty
+  , Just cls <- tyConClass_maybe tc
+  =    cls `hasKey` heqTyConKey
+    || cls `hasKey` eqTyConKey
+    || cls `hasKey` coercibleTyConKey
+  | otherwise
+  = False
+
+--------------------------------------------------------------------------------
+
+#if !MIN_VERSION_ghc(9,6,0)
+thNameToGhcNameIO :: HscEnv -> TH.Name -> IO (Maybe Name)
+thNameToGhcNameIO hscEnv th_name
+  =  do { names <- mapMaybeM do_lookup (thRdrNameGuesses th_name)
+        ; return (listToMaybe names) }
+  where
+    do_lookup rdr_name
+      | Just n <- isExact_maybe rdr_name
+      = return $ if isExternalName n then Just n else Nothing
+      | Just (rdr_mod, rdr_occ) <- isOrig_maybe rdr_name
+#if MIN_VERSION_ghc(9,3,0)
+      = Just <$> lookupNameCache (hsc_NC hscEnv) rdr_mod rdr_occ
+#else
+      = Just <$> lookupOrigIO hscEnv rdr_mod rdr_occ
+#endif
+      | otherwise
+      = return Nothing
 #endif
 
 --------------------------------------------------------------------------------
src/GHC/TcPlugin/API/Internal.hs view
@@ -69,6 +69,8 @@   ( TypeError, ErrorMessage(..) )
 
 -- transformers
+import Control.Monad.IO.Class
+  ( MonadIO ( liftIO ) )
 import Control.Monad.Trans.Reader
   ( ReaderT(..) )
 
@@ -464,6 +466,10 @@     adaptUserStop :: ( userDefs -> TcPluginM Stop () ) -> TcPluginDefs userDefs -> GHC.TcPluginM ()
     adaptUserStop userStop ( TcPluginDefs { tcPluginUserDefs } ) =
       tcPluginStopM $ userStop tcPluginUserDefs
+
+-- | @since 0.15.0.0
+instance ( Monad ( TcPluginM s ), MonadTcPlugin ( TcPluginM s ) ) => MonadIO ( TcPluginM s ) where
+  liftIO = unsafeLiftTcM . liftIO
 
 -- | Monads for type-checking plugins which are able to emit new constraints
 -- and throw errors.