Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
GHC.TcPlugin.API
Description
This module provides a unified interface for writing type-checking plugins for GHC.
It attempts to re-export all the functionality from GHC that is relevant to plugin authors, as well as providing utility functions to streamline certain common operations such as creating evidence (to solve constraints), rewriting type family applications, throwing custom type errors.
Consider making use of the table of contents to help navigate this documentation; don't hesitate to jump between sections to get an overview of the relevant aspects.
For an illustration of the functionality, check the examples in the associated GitHub repository.
The internal module GHC.TcPlugin.API.Internal can be used to directly
lift and unlift computations in GHC's TcM
monad, but it is hoped that
the interface provided in this module is sufficient.
Synopsis
- data TcPlugin = forall s.TcPlugin {
- tcPluginInit :: TcPluginM Init s
- tcPluginSolve :: s -> TcPluginSolver
- tcPluginRewrite :: s -> UniqFM TyCon TcPluginRewriter
- tcPluginStop :: s -> TcPluginM Stop ()
- mkTcPlugin :: TcPlugin -> TcPlugin
- data TcPluginStage
- class (Monad m, forall x y. Coercible x y => Coercible (m x) (m y)) => MonadTcPlugin (m :: Type -> Type)
- data family TcPluginM (s :: TcPluginStage) :: Type -> Type
- tcPluginIO :: MonadTcPlugin m => IO a -> m a
- class MonadTcPlugin m => MonadTcPluginWork m
- data TcPluginErrorMessage
- mkTcPluginErrorTy :: MonadTcPluginWork m => TcPluginErrorMessage -> m PredType
- findImportedModule :: MonadTcPlugin m => ModuleName -> PkgQual -> m FindResult
- resolveImport :: MonadTcPlugin m => ModuleName -> Maybe FastString -> m PkgQual
- fsLit :: String -> FastString
- unpackFS :: FastString -> String
- mkModuleName :: String -> ModuleName
- unitIdFS :: UnitId -> FastString
- stringToUnitId :: String -> UnitId
- pkgQualToPkgName :: PkgQual -> Maybe String
- type Module = GenModule Unit
- data ModuleName
- data FindResult
- = Found ModLocation Module
- | NoPackage Unit
- | FoundMultiple [(Module, ModuleOrigin)]
- | NotFound {
- fr_paths :: [FilePath]
- fr_pkg :: Maybe Unit
- fr_mods_hidden :: [Unit]
- fr_pkgs_hidden :: [Unit]
- fr_unusables :: [(Unit, UnusableUnitReason)]
- fr_suggestions :: [ModuleSuggestion]
- data UnitId
- data PkgQual
- mkVarOcc :: String -> OccName
- mkDataOcc :: String -> OccName
- mkTyVarOcc :: String -> OccName
- mkTcOcc :: String -> OccName
- mkClsOcc :: String -> OccName
- lookupOrig :: MonadTcPlugin m => Module -> OccName -> m Name
- tcLookupTyCon :: MonadTcPlugin m => Name -> m TyCon
- tcLookupDataCon :: MonadTcPlugin m => Name -> m DataCon
- tcLookupClass :: MonadTcPlugin m => Name -> m Class
- tcLookupGlobal :: MonadTcPlugin m => Name -> m TyThing
- tcLookup :: MonadTcPlugin m => Name -> m TcTyThing
- tcLookupId :: MonadTcPlugin m => Name -> m Id
- promoteDataCon :: DataCon -> TyCon
- type TcPluginSolver = [Ct] -> [Ct] -> TcPluginM Solve TcPluginSolveResult
- data TcPluginSolveResult where
- TcPluginSolveResult {
- tcPluginInsolubleCts :: [Ct]
- tcPluginSolvedCts :: [(EvTerm, Ct)]
- tcPluginNewCts :: [Ct]
- pattern TcPluginOk :: [(EvTerm, Ct)] -> [Ct] -> TcPluginSolveResult
- pattern TcPluginContradiction :: [Ct] -> TcPluginSolveResult
- TcPluginSolveResult {
- tcPluginTrace :: MonadTcPlugin m => String -> SDoc -> m ()
- mkNonCanonical :: CtEvidence -> Ct
- data Pred
- pattern ClassPred :: Class -> [Type] -> Pred
- pattern EqPred :: EqRel -> Type -> Type -> Pred
- pattern IrredPred :: PredType -> Pred
- pattern ForAllPred :: [TyVar] -> [PredType] -> PredType -> Pred
- classifyPredType :: PredType -> Pred
- ctPred :: Ct -> PredType
- type TyVar = Var
- type CoVar = Id
- data MetaDetails
- data MetaInfo
- isSkolemTyVar :: TcTyVar -> Bool
- isMetaTyVar :: TcTyVar -> Bool
- isFilledMetaTyVar_maybe :: TcTyVar -> TcM (Maybe Type)
- writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> TcM ()
- readTcRef :: TcRef a -> TcRnIf gbl lcl a
- writeTcRef :: TcRef a -> a -> TcRnIf gbl lcl ()
- eqType :: Type -> Type -> Bool
- ctLoc :: Ct -> CtLoc
- ctEvidence :: Ct -> CtEvidence
- ctFlavour :: Ct -> CtFlavour
- ctEqRel :: Ct -> EqRel
- ctOrigin :: Ct -> CtOrigin
- mkPluginUnivCo :: String -> Role -> [Coercion] -> TcType -> TcType -> Coercion
- newCoercionHole :: PredType -> TcPluginM Solve CoercionHole
- mkReflCo :: Role -> Type -> Coercion
- mkSymCo :: Coercion -> Coercion
- mkTransCo :: Coercion -> Coercion -> Coercion
- mkUnivCo :: UnivCoProvenance -> Role -> Type -> Type -> Coercion
- mkCoercionTy :: Coercion -> Type
- isCoercionTy :: Type -> Bool
- isCoercionTy_maybe :: Type -> Maybe Coercion
- ctEvCoercion :: HasDebugCallStack => CtEvidence -> TcCoercion
- mkPluginUnivEvTerm :: String -> Role -> [Coercion] -> TcType -> TcType -> EvTerm
- evDataConApp :: DataCon -> [Type] -> [EvExpr] -> EvTerm
- newEvVar :: PredType -> TcPluginM Solve EvVar
- setEvBind :: EvBind -> TcPluginM Solve ()
- evCoercion :: TcCoercion -> EvTerm
- evCast :: EvExpr -> TcCoercion -> EvTerm
- ctEvExpr :: HasDebugCallStack => CtEvidence -> EvExpr
- askEvBinds :: TcPluginM Solve EvBindsVar
- lookupEvBind :: EvBindMap -> EvVar -> Maybe EvBind
- eb_lhs :: EvBind -> EvVar
- eb_rhs :: EvBind -> EvTerm
- newName :: OccName -> TcM Name
- mkLocalId :: HasDebugCallStack => Name -> Mult -> Type -> Id
- mkTyVar :: Name -> Kind -> TyVar
- ctev_pred :: CtEvidence -> TcPredType
- ctev_evar :: CtEvidence -> EvVar
- ctev_loc :: CtEvidence -> CtLoc
- ctev_dest :: CtEvidence -> TcEvDest
- classDataCon :: Class -> DataCon
- getInstEnvs :: MonadTcPlugin m => m InstEnvs
- newWanted :: MonadTcPluginWork m => CtLoc -> PredType -> m CtEvidence
- newGiven :: CtLoc -> PredType -> EvExpr -> TcPluginM Solve CtEvidence
- mkClassPred :: Class -> [Type] -> PredType
- mkEqPredRole :: Role -> Type -> Type -> PredType
- askDeriveds :: TcPluginM Solve [Ct]
- setCtLocM :: MonadTcPluginWork m => CtLoc -> m a -> m a
- setCtLocRewriteM :: TcPluginM Rewrite a -> TcPluginM Rewrite a
- bumpCtLocDepth :: CtLoc -> CtLoc
- type TcPluginRewriter = [Ct] -> [Type] -> TcPluginM Rewrite TcPluginRewriteResult
- data TcPluginRewriteResult
- matchFam :: MonadTcPlugin m => TyCon -> [TcType] -> m (Maybe Reduction)
- getFamInstEnvs :: MonadTcPlugin m => m (FamInstEnv, FamInstEnv)
- data FamInstEnv
- askRewriteEnv :: TcPluginM Rewrite RewriteEnv
- rewriteEnvCtLoc :: RewriteEnv -> CtLoc
- data RewriteEnv
- mkTyFamAppReduction :: String -> Role -> [Coercion] -> TyCon -> [TcType] -> TcType -> Reduction
- data Reduction = Reduction {}
- newUnique :: MonadTcPlugin m => m Unique
- newFlexiTyVar :: MonadTcPlugin m => Kind -> m TcTyVar
- isTouchableTcPluginM :: MonadTcPlugin m => TcTyVar -> m Bool
- mkTyVarTy :: TyVar -> Type
- mkTyVarTys :: [TyVar] -> [Type]
- isTyVarTy :: Type -> Bool
- getTyVar_maybe :: Type -> Maybe TyVar
- type TcType = Type
- type TcTyVar = Var
- data Unique
- type Kind = Type
- mkNumLitTy :: Integer -> Type
- isNumLitTy :: Type -> Maybe Integer
- mkStrLitTy :: FastString -> Type
- isStrLitTy :: Type -> Maybe FastString
- mkTyConTy :: TyCon -> Type
- mkTyConApp :: TyCon -> [Type] -> Type
- mkAppTy :: Type -> Type -> Type
- mkAppTys :: Type -> [Type] -> Type
- splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])
- tyConAppTyConPicky_maybe :: Type -> Maybe TyCon
- tyConAppTyCon_maybe :: Type -> Maybe TyCon
- splitAppTy_maybe :: Type -> Maybe (Type, Type)
- splitAppTys :: Type -> (Type, [Type])
- mkVisFunTyMany :: HasDebugCallStack => Type -> Type -> Type
- mkVisFunTysMany :: [Type] -> Type -> Type
- mkInvisFunTy :: HasDebugCallStack => Type -> Type -> Type
- mkInvisFunTys :: HasDebugCallStack => [Type] -> Type -> Type
- mkForAllTy :: ForAllTyBinder -> Type -> Type
- mkForAllTys :: [ForAllTyBinder] -> Type -> Type
- mkPiTy :: PiTyBinder -> Type -> Type
- mkPiTys :: [PiTyBinder] -> Type -> Type
- type Mult = Type
- pattern OneTy :: Mult
- pattern ManyTy :: Mult
- zonkTcType :: MonadTcPluginWork m => TcType -> m TcType
- zonkCt :: MonadTcPluginWork m => Ct -> m Ct
- panic :: HasCallStack => String -> a
- pprPanic :: HasCallStack => String -> SDoc -> a
- data UniqDFM key ele
- lookupUDFM :: Uniquable key => UniqDFM key elt -> key -> Maybe elt
- lookupUDFM_Directly :: UniqDFM key elt -> Unique -> Maybe elt
- elemUDFM :: Uniquable key => key -> UniqDFM key elt -> Bool
- data UniqFM key ele
- emptyUFM :: UniqFM key elt
- listToUFM :: Uniquable key => [(key, elt)] -> UniqFM key elt
- getEnvs :: MonadTcPlugin m => m (TcGblEnv, TcLclEnv)
- data TcS a
- data InertSet
- getInertSet :: TcS InertSet
- setInertSet :: InertSet -> TcS ()
- getTcEvBindsMap :: EvBindsVar -> TcS EvBindMap
- setTcEvBindsMap :: EvBindsVar -> EvBindMap -> TcS ()
- data Boxity
- data PromotionFlag
- data TupleSort
- type Arity = Int
- isPromoted :: PromotionFlag -> Bool
- data Name
- data OccName
- data TyThing
- data TcTyThing
- class Monad m => MonadThings (m :: Type -> Type) where
- lookupThing :: Name -> m TyThing
- lookupId :: Name -> m Id
- lookupDataCon :: Name -> m DataCon
- lookupTyCon :: Name -> m TyCon
- data Class
- data DataCon
- data TyCon
- type Id = Var
- data FastString
- data EqRel
- type FunDep a = ([a], [a])
- data CtFlavour
- data Ct
- data CtLoc
- data CtEvidence
- data CtOrigin
- data QCInst
- data Type
- type PredType = Type
- data InstEnvs
- data TcLevel
- data Coercion
- data Role
- data UnivCoProvenance
- data CoercionHole = CoercionHole {}
- data EvBind
- data EvTerm = EvExpr EvExpr
- type EvVar = EvId
- type EvExpr = CoreExpr
- data EvBindsVar
- data Expr b
- type CoreBndr = Var
- type CoreExpr = Expr CoreBndr
- data TcEvDest
- data TcGblEnv
- data TcLclEnv
- data GenLocated l e = L l e
- type Located = GenLocated SrcSpan
- type RealLocated = GenLocated RealSrcSpan
- unLoc :: GenLocated l e -> e
- getLoc :: GenLocated l e -> l
- data SDoc
- class Outputable a where
Basic TcPlugin functionality
The TcPlugin
type
A record containing all the stages necessary for the operation of a type-checking plugin, as defined in this API.
Note: this is not the same record as GHC's built-in
TcPlugin
record. Use mkTcPlugin
for the conversion.
To create a type-checking plugin, define something of this type
and then call mkTcPlugin
on the result.
This will return something that can be passed to Plugin
:
plugin :: GHC.Plugins.Plugin plugin = GHC.Plugins.defaultPlugin { GHC.Plugins.tcPlugin = \ args -> Just $ GHC.TcPlugin.API.mkTcPlugin ( myTcPlugin args ) } myTcPlugin :: [String] -> GHC.TcPlugin.API.TcPlugin myTcPlugin args = ...
Constructors
forall s. TcPlugin | |
Fields
|
Arguments
:: TcPlugin | type-checking plugin written with this library |
-> TcPlugin | type-checking plugin for GHC |
Use this function to create a type-checker plugin to pass to GHC.
Plugin state
A type-checker plugin can define its own state, corresponding to the existential parameter s
in the definition of TcPlugin
.
This allows a plugin to look up information a single time
on initialisation, and pass it on for access in all further invocations of the plugin.
For example:
data MyDefinitions { myTyFam :: !TyCon, myClass :: !Class }
Usually, the tcPluginInit
part of the plugin looks up all this information and returns it:
myTcPluginInit :: TcPluginM Init MyDefinitions
This step should also be used to initialise any external tools, such as an external SMT solver.
This information will then be passed to other stages of the plugin:
myTcPluginSolve :: MyDefinitions -> TcPluginSolver
The type-checking plugin monads
Different stages of type-checking plugins have access to different information.
For a unified interface, an MTL-style approach is used, with the MonadTcPlugin
typeclass providing overloading (for operations that work in all stages).
data TcPluginStage Source #
Stage of a type-checking plugin, used as a data kind.
class (Monad m, forall x y. Coercible x y => Coercible (m x) (m y)) => MonadTcPlugin (m :: Type -> Type) Source #
A MonadTcPlugin
is essentially a reader monad over GHC's TcM
monad.
This means we have both a lift
and an unlift
operation,
similar to MonadUnliftIO
or MonadBaseControl
.
See for instance unsafeLiftThroughTcM
, which is an example of function that
one would not be able to write using only a lift
operation.
Note that you must import the internal module in order to access the methods. Please report a bug if you find yourself needing this functionality.
Minimal complete definition
Instances
MonadTcPlugin (TcPluginM 'Init) Source # | |
Defined in GHC.TcPlugin.API.Internal | |
MonadTcPlugin (TcPluginM 'Rewrite) Source # | |
Defined in GHC.TcPlugin.API.Internal | |
MonadTcPlugin (TcPluginM 'Solve) Source # | |
Defined in GHC.TcPlugin.API.Internal | |
MonadTcPlugin (TcPluginM 'Stop) Source # | |
Defined in GHC.TcPlugin.API.Internal |
data family TcPluginM (s :: TcPluginStage) :: Type -> Type Source #
The monad used for a type-checker plugin, parametrised by
the TcPluginStage
of the plugin.
Instances
tcPluginIO :: MonadTcPlugin m => IO a -> m a Source #
Run an IO
computation within the plugin.
Emitting new work, and throwing type-errors
Some operations only make sense in the two main phases, solving and rewriting.
This is captured by the MonadTcPluginWork
typeclass, which allows emitting
new work, including throwing type errors.
class MonadTcPlugin m => MonadTcPluginWork m Source #
Monads for type-checking plugins which are able to emit new constraints and throw errors.
These operations are supported by the monads that tcPluginSolve
and tcPluginRewrite
use; it is not possible to emit work or
throw type errors in tcPluginInit
or tcPluginStop
.
See mkTcPluginErrorTy
and emitWork
for functions
which require this typeclass.
Instances
(TypeError ('Text "Cannot emit new work in 'tcPluginInit'.") :: Constraint) => MonadTcPluginWork (TcPluginM 'Init) Source # | |
Defined in GHC.TcPlugin.API.Internal Methods askBuiltins :: TcPluginM 'Init BuiltinDefs | |
MonadTcPluginWork (TcPluginM 'Rewrite) Source # | |
Defined in GHC.TcPlugin.API.Internal Methods askBuiltins :: TcPluginM 'Rewrite BuiltinDefs | |
MonadTcPluginWork (TcPluginM 'Solve) Source # | |
Defined in GHC.TcPlugin.API.Internal Methods askBuiltins :: TcPluginM 'Solve BuiltinDefs | |
(TypeError ('Text "Cannot emit new work in 'tcPluginStop'.") :: Constraint) => MonadTcPluginWork (TcPluginM 'Stop) Source # | |
Defined in GHC.TcPlugin.API.Internal Methods askBuiltins :: TcPluginM 'Stop BuiltinDefs |
data TcPluginErrorMessage Source #
Use this type like ErrorMessage
to write an error message.
This error message can then be thrown at the type-level by the plugin,
by emitting a wanted constraint whose predicate is obtained from mkTcPluginErrorTy
.
A CtLoc
will still need to be provided in order to inform GHC of the
origin of the error (e.g.: which part of the source code should be
highlighted?). See setCtLocM
.
Constructors
Txt !String | Show the text as is. |
PrintType !Type | Pretty print the given type. |
(:|:) !TcPluginErrorMessage !TcPluginErrorMessage infixl 5 | Put two messages side by side. |
(:-:) !TcPluginErrorMessage !TcPluginErrorMessage infixl 6 | Stack two messages vertically. |
mkTcPluginErrorTy :: MonadTcPluginWork m => TcPluginErrorMessage -> m PredType Source #
Name resolution
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
:
lookupMyModule :: MonadTcPlugin m => m Module lookupMyModule = do let modlName = mkModuleName "MyModule" pkgName = Just $ fsLit "my-pkg" pkgQual <- resolveImport modlName pkgName findResult <- findImportedModule modlName pkgQual case findResult of Found _ myModule -> pure myModule _ -> error "MyPlugin couldn't find MyModule in my-pkg" lookupMyFam :: MonadTcPlugin m => Module -> m TyCon lookupMyFam myModule = tcLookupTyCon =<< lookupOrig myModule ( mkTcOcc "MyFam" )
Most of these operations should be performed in tcPluginInit
, and passed on
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
Use these functions to lookup a module, from the current package or imported packages.
Arguments
:: MonadTcPlugin m | |
=> ModuleName | Module name, e.g. |
-> PkgQual | Package qualifier. See |
-> m FindResult |
Lookup a Haskell module, with an optional package qualifier.
Arguments
:: MonadTcPlugin m | |
=> ModuleName | Module name to import from |
-> Maybe FastString | Optional package qualifier |
-> m PkgQual |
Resolve import
fsLit :: String -> FastString #
unpackFS :: FastString -> String #
Lazily unpacks and decodes the FastString
mkModuleName :: String -> ModuleName #
unitIdFS :: UnitId -> FastString #
The full hashed unit identifier, including the component id and the hash.
stringToUnitId :: String -> UnitId #
data ModuleName #
A ModuleName is essentially a simple string, e.g. Data.List
.
Instances
data FindResult #
The result of searching for an imported module.
NB: FindResult manages both user source-import lookups
(which can result in GenModule
) as well as direct imports
for interfaces (which always result in InstalledModule
).
Constructors
Found ModLocation Module | The module was found |
NoPackage Unit | The requested unit was not found |
FoundMultiple [(Module, ModuleOrigin)] | _Error_: both in multiple packages |
NotFound | Not found |
Fields
|
A UnitId identifies a built library in a database and is used to generate unique symbols, etc. It's usually of the form:
pkgname-1.2:libname+hash
These UnitId are provided to us via the -this-unit-id
flag.
The library in question may be definite or indefinite; if it is indefinite, none of the holes have been filled (we never install partially instantiated libraries as we can cheaply instantiate them on-the-fly, cf VirtUnit). Put another way, an installed unit id is either fully instantiated, or not instantiated at all.
Instances
Data Unit | |
Defined in GHC.Unit.Types Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Unit -> c Unit # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Unit # dataTypeOf :: Unit -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Unit) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Unit) # gmapT :: (forall b. Data b => b -> b) -> Unit -> Unit # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Unit -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Unit -> r # gmapQ :: (forall d. Data d => d -> u) -> Unit -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Unit -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Unit -> m Unit # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Unit -> m Unit # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Unit -> m Unit # | |
Data UnitId | |
Defined in GHC.Unit.Types Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> UnitId -> c UnitId # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c UnitId # toConstr :: UnitId -> Constr # dataTypeOf :: UnitId -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c UnitId) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitId) # gmapT :: (forall b. Data b => b -> b) -> UnitId -> UnitId # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UnitId -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UnitId -> r # gmapQ :: (forall d. Data d => d -> u) -> UnitId -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> UnitId -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> UnitId -> m UnitId # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> UnitId -> m UnitId # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> UnitId -> m UnitId # | |
Show Unit | |
NFData Unit | |
Defined in GHC.Unit.Types | |
Uniquable Module | |
Defined in GHC.Unit.Types | |
Uniquable UnitId | |
Defined in GHC.Unit.Types | |
IsUnitId UnitId | |
Defined in GHC.Unit.Types Methods unitFS :: UnitId -> FastString # | |
Binary InstantiatedUnit | |
Defined in GHC.Unit.Types Methods put_ :: BinHandle -> InstantiatedUnit -> IO () # put :: BinHandle -> InstantiatedUnit -> IO (Bin InstantiatedUnit) # get :: BinHandle -> IO InstantiatedUnit # | |
Binary Unit | |
Binary UnitId | |
Outputable InstalledModule | |
Defined in GHC.Unit.Types Methods ppr :: InstalledModule -> SDoc # | |
Outputable InstantiatedModule | |
Defined in GHC.Unit.Types Methods ppr :: InstantiatedModule -> SDoc # | |
Outputable InstantiatedUnit | |
Defined in GHC.Unit.Types Methods ppr :: InstantiatedUnit -> SDoc # | |
Outputable Module | |
Defined in GHC.Unit.Types | |
Outputable Unit | |
Defined in GHC.Unit.Types | |
Outputable UnitId | |
Defined in GHC.Unit.Types | |
Eq UnitId | |
Ord Unit | |
Ord UnitId | |
Package-qualifier after renaming
Renaming detects if "this" or the unit-id of the home-unit was used as a package qualifier.
Instances
Data PkgQual | |
Defined in GHC.Types.PkgQual Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> PkgQual -> c PkgQual # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c PkgQual # toConstr :: PkgQual -> Constr # dataTypeOf :: PkgQual -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c PkgQual) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PkgQual) # gmapT :: (forall b. Data b => b -> b) -> PkgQual -> PkgQual # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> PkgQual -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> PkgQual -> r # gmapQ :: (forall d. Data d => d -> u) -> PkgQual -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> PkgQual -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> PkgQual -> m PkgQual # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> PkgQual -> m PkgQual # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> PkgQual -> m PkgQual # | |
Outputable PkgQual | |
Defined in GHC.Types.PkgQual | |
Eq PkgQual | |
Ord PkgQual | |
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).
mkTyVarOcc :: String -> OccName #
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 :: MonadTcPlugin m => Module -> OccName -> m Name Source #
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
using their Name
.
tcLookupTyCon :: MonadTcPlugin m => Name -> m TyCon Source #
Lookup a type constructor from its name (datatype, type synonym or type family).
tcLookupDataCon :: MonadTcPlugin m => Name -> m DataCon Source #
tcLookupClass :: MonadTcPlugin m => Name -> m Class Source #
Lookup a typeclass from its name.
tcLookupGlobal :: MonadTcPlugin m => Name -> m TyThing Source #
Lookup a global typecheckable-thing from its name.
tcLookup :: MonadTcPlugin m => Name -> m TcTyThing Source #
Lookup a typecheckable-thing available in a local context, such as a local type variable.
tcLookupId :: MonadTcPlugin m => Name -> m Id Source #
Lookup an identifier, such as a type variable.
promoteDataCon :: DataCon -> TyCon #
Constraint solving
Type-checking plugins will often want to manipulate constraints, e.g. solve constraints that GHC can't solve on its own, or emit their own constraints.
There are two different constraint flavours:
- Given constraints, which are already known and have evidence associated to them,
- Wanted constraints, for which evidence has not yet been found.
When GHC can't solve a Wanted constraint, it will get reported to the user as a type error.
type TcPluginSolver Source #
Arguments
= [Ct] | Givens |
-> [Ct] | Wanteds |
-> TcPluginM Solve TcPluginSolveResult |
The solve
function of a type-checking plugin takes in Given and Wanted
constraints, and should return a TcPluginSolveResult
indicating which Wanted constraints it could solve, or whether any are
insoluble.
data TcPluginSolveResult #
Result of running a solver plugin.
Constructors
TcPluginSolveResult | |
Fields
|
Bundled Patterns
pattern TcPluginOk :: [(EvTerm, Ct)] -> [Ct] -> TcPluginSolveResult | The plugin has not found any contradictions, The first field is for constraints that were solved. The second field contains new work, that should be processed by the constraint solver. |
pattern TcPluginContradiction :: [Ct] -> TcPluginSolveResult | The plugin found a contradiction. The returned constraints are removed from the inert set, and recorded as insoluble. The returned list of constraints should never be empty. |
The tcPluginSolve
method of a typechecker plugin will be invoked
in two different ways:
- to simplify Given constraints. In this case, the
tcPluginSolve
function will not be passed any Wanted constraints, and - to solve Wanted constraints.
The plugin can then respond in one of two ways:
- with
TcPluginOk solved new
, wheresolved
is a list of solved constraints andnew
is a list of new constraints for GHC to process; - with
TcPluginContradiction contras
, wherecontras
is a list of impossible constraints, so that they can be turned into errors.
In both cases, the plugin must respond with constraints of the same flavour, i.e. in (1) it should return only Givens, and for (2) it should return only Wanteds; all other constraints will be ignored.
Getting started with constraint solving
To get started, it can be helpful to immediately print out all the constraints
that the plugin is given, using tcPluginTrace
:
solver _ givens wanteds = do tcPluginTrace "---Plugin start---" (ppr givens $$ ppr wanteds) pure $ TcPluginOk [] []
This creates a plugin that prints outs the constraints it is passed, without doing anything with them.
To see this output, you will need to pass the flags -ddump-tc-trace
and -ddump-to-file
to GHC. This will output the trace as a log file,
and you can search for "---Plugin start---"
to find the plugin inputs.
Note that pretty-printing in GHC is done using the Outputable
type class.
We use its ppr
method to turn things into pretty-printable documents,
and ($$)
to combine documents vertically.
If you need more capabilities for pretty-printing documents,
import GHC's GHC.Utils.Outputable module.
Arguments
:: MonadTcPlugin m | |
=> String | Text at the top of the debug message. |
-> SDoc | Formatted document to print (use the |
-> m () |
Output some debugging information within the plugin.
Inspecting constraints & predicates
Canonical and non-canonical constraints
A constraint in GHC starts out as "non-canonical", which means that GHC doesn't know what type of constraint it is. GHC will inspect the constraint to turn it into a canonical form (class constraint, equality constraint, etc.) which satisfies certain invariants used during constraint solving.
Thus, whenever emitting new constraints, it is usually best to emit a non-canonical constraint, letting GHC canonicalise it.
mkNonCanonical :: CtEvidence -> Ct #
Predicates
A type-checking plugin will usually need to inspect constraints, so that it can pick out the constraints it is going to interact with.
In general, type-checking plugins can encounter all sorts of constraints,
whether in canonical form or not.
In order to handle these constraints in a uniform manner, it is usually
preferable to inspect each constraint's predicate, which can be obtained
by using classifyPredType
and ctPred
.
This allows the plugin to determine what kind of constraints it is dealing with:
- an equality constraint? at
Nominal
orRepresentational
role? - a type-class constraint? for which class?
- an irreducible constraint, e.g. something of the form
c a
? - a quantified constraint?
pattern ForAllPred :: [TyVar] -> [PredType] -> PredType -> Pred #
A quantified predicate.
See Note [Quantified constraints] in GHC.Tc.Solver.Canonical
classifyPredType :: PredType -> Pred #
Handling type variables
data MetaDetails #
Instances
Outputable MetaDetails | |
Defined in GHC.Tc.Utils.TcType Methods ppr :: MetaDetails -> SDoc # |
What restrictions are on this metavariable around unification? These are checked in GHC.Tc.Utils.Unify.startSolvingByUnification.
Instances
Outputable MetaInfo | |
Defined in GHC.Tc.Utils.TcType |
isSkolemTyVar :: TcTyVar -> Bool #
isMetaTyVar :: TcTyVar -> Bool #
writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> TcM () #
writeTcRef :: TcRef a -> a -> TcRnIf gbl lcl () #
Some further functions for inspecting constraints
eqType :: Type -> Type -> Bool #
Type equality on source types. Does not look through newtypes
,
PredType
s or type families, but it does look through type synonyms.
This first checks that the kinds of the types are equal and then
checks whether the types are equal, ignoring casts and coercions.
(The kind check is a recursive call, but since all kinds have type
Type
, there is no need to check the types of kinds.)
See also Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep.
ctEvidence :: Ct -> CtEvidence #
Constraint evidence
Coercions
Coercion
s are the evidence for type equalities.
As such, when proving an equality, a type-checker plugin needs
to construct the associated coercions.
Arguments
:: String | Name of equality (for the plugin's internal use, or for debugging) |
-> Role | |
-> [Coercion] | Evidence that this proof term depends on (use |
-> TcType | LHS |
-> TcType | RHS |
-> Coercion |
Conjure up a coercion witnessing an equality between two types
at the given Role
(Nominal
or Representational
).
This amounts to telling GHC "believe me, these things are equal".
The plugin is responsible for not emitting any unsound coercions,
such as a coercion between Int
and Float
.
newCoercionHole :: PredType -> TcPluginM Solve CoercionHole Source #
Create a fresh coercion hole.
mkSymCo :: Coercion -> Coercion #
Create a symmetric version of the given Coercion
that asserts
equality between the same types but in the other "direction", so
a kind of t1 ~ t2
becomes the kind t2 ~ t1
.
Arguments
:: UnivCoProvenance | |
-> Role | role of the built coercion, "r" |
-> Type | t1 :: k1 |
-> Type | t2 :: k2 |
-> Coercion | :: t1 ~r t2 |
Make a universal coercion between two arbitrary types.
mkCoercionTy :: Coercion -> Type #
isCoercionTy :: Type -> Bool #
isCoercionTy_maybe :: Type -> Maybe Coercion #
Depending on outer Givens
When a plugin returns a coercion that depends on outer Given constraints,
it should declare this dependency using the '[Coercion]' argument to
functions such as mkPluginUnivCo
, mkPluginUnivEvTerm
and mkTyFamAppReduction
in order to avoid this coercion getting floated out past such enclosing
Givens.
You can use ctEvCoercion
to obtain the coercion underlying an equality
constraint (whether Given or Wanted). It is not possible to declare
a dependency on non-equality constraints, and calling ctEvCoercion
on a non-equality constraint will cause a crash.
ctEvCoercion :: HasDebugCallStack => CtEvidence -> TcCoercion #
Evidence terms
Typeclass constraints have a different notion of evidence: evidence terms.
A plugin that wants to solve a class constraint will need to provide an evidence term. Such evidence can be created from scratch, or it can be obtained by combining evidence that is already available.
Arguments
:: String | Name of equality (for the plugin's internal use, or for debugging) |
-> Role | |
-> [Coercion] | Evidence that this proof term depends on (use |
-> TcType | LHS |
-> TcType | RHS |
-> EvTerm |
Conjure up an evidence term for an equality between two types
at the given Role
(Nominal
or Representational
).
This can be used to supply a proof of a wanted equality in TcPluginOk
.
The plugin is responsible for not emitting any unsound equalities,
such as an equality between Int
and Float
.
evCoercion :: TcCoercion -> EvTerm #
evCast :: EvExpr -> TcCoercion -> EvTerm #
d |> co
ctEvExpr :: HasDebugCallStack => CtEvidence -> EvExpr #
askEvBinds :: TcPluginM Solve EvBindsVar Source #
Ask for the evidence currently gathered by the type-checker.
Only available in the solver part of the type-checking plugin.
mkLocalId :: HasDebugCallStack => Name -> Mult -> Type -> Id #
For an explanation of global vs. local Id
s, see GHC.Types.Var
ctev_pred :: CtEvidence -> TcPredType #
ctev_evar :: CtEvidence -> EvVar #
ctev_loc :: CtEvidence -> CtLoc #
ctev_dest :: CtEvidence -> TcEvDest #
Class dictionaries
To create evidence terms for class constraints, type-checking plugins need to be able to construct the appropriate dictionaries containing the values for the class methods.
The class dictionary constructor can be obtained using classDataCon
.
Functions from GHC.Core.Make, which is re-exported by this library,
will be useful for constructing the necessary terms
For instance, we can apply the class data constructor using mkCoreConApps
.
Remember that the type-level arguments (the typeclass variables) come first,
before the actual evidence term (the class dictionary expression).
classDataCon :: Class -> DataCon #
Class instances
In some cases, a type-checking plugin might need to access the class instances that are currently in scope, e.g. to obtain certain evidence terms.
getInstEnvs :: MonadTcPlugin m => m InstEnvs Source #
Obtain all currently-reachable typeclass instances.
Emitting new constraints
newWanted :: MonadTcPluginWork m => CtLoc -> PredType -> m CtEvidence Source #
Create a new Wanted constraint.
Requires a location (so that error messages can say where the constraint came from, what things were in scope at that point, etc), as well as the actual constraint (encoded as a type).
newGiven :: CtLoc -> PredType -> EvExpr -> TcPluginM Solve CtEvidence Source #
Create a new Given constraint.
Unlike newWanted
, we need to supply evidence for this constraint.
The following functions allow plugins to create constraints for typeclasses and type equalities.
mkClassPred :: Class -> [Type] -> PredType #
mkEqPredRole :: Role -> Type -> Type -> PredType Source #
Makes an unlifted equality predicate at the given role
(either Nominal
or Representational
).
Deriveds
Derived constraints are like Wanted constraints, except that they don't require evidence in order to be solved, and won't be seen in error messages if they go unsolved.
Solver plugins usually ignore this type of constraint entirely. They occur mostly when dealing with functional dependencies and type-family injectivity annotations.
GHC 9.4 removes this flavour of constraints entirely, subsuming their uses into Wanted constraints.
askDeriveds :: TcPluginM Solve [Ct] Source #
Ask for the Derived constraints that the solver was provided with.
Always returns the empty list on GHC 9.4 or above.
Location information and CtLoc
s
When creating new constraints, one still needs a mechanism allowing GHC to report a certain source location associated to them when throwing an error, as well as other information the type-checker was aware of at that point (e.g. available instances, given constraints, etc).
This is the purpose of CtLoc
.
setCtLocM :: MonadTcPluginWork m => CtLoc -> m a -> m a Source #
Set the location information for a computation.
setCtLocRewriteM :: TcPluginM Rewrite a -> TcPluginM Rewrite a Source #
Use the RewriteEnv
to set the CtLoc
for a computation.
bumpCtLocDepth
adds one to the "depth" of the constraint.
Can help avoid loops, by triggering a "maximum depth exceeded" error.
bumpCtLocDepth :: CtLoc -> CtLoc #
Rewriting type-family applications
type TcPluginRewriter Source #
Arguments
= [Ct] | Givens |
-> [Type] | Type family arguments (saturated) |
-> TcPluginM Rewrite TcPluginRewriteResult |
For rewriting type family applications, a type-checking plugin provides
a function of this type for each type family TyCon
.
The function is provided with the current set of Given constraints, together with the arguments to the type family. The type family application will always be fully saturated.
data TcPluginRewriteResult #
Constructors
TcPluginNoRewrite | The plugin does not rewrite the type family application. |
TcPluginRewriteTo | The plugin rewrites the type family application
providing a rewriting together with evidence: a The plugin can also emit additional Wanted constraints. |
Fields
|
Querying for type family reductions
matchFam :: MonadTcPlugin m => TyCon -> [TcType] -> m (Maybe Reduction) Source #
Ask GHC what a type family application reduces to.
Warning: can cause a loop when used within tcPluginRewrite
.
getFamInstEnvs :: MonadTcPlugin m => m (FamInstEnv, FamInstEnv) Source #
Obtain all currently-reachable data/type family instances.
First result: external instances. Second result: instances in the current home package.
data FamInstEnv #
Instances
Outputable FamInstEnv | |
Defined in GHC.Core.FamInstEnv Methods ppr :: FamInstEnv -> SDoc # |
Specifying type family reductions
A plugin that wants to rewrite a type family application must provide two pieces of information:
- the type that the type family application reduces to,
- evidence for this reduction, i.e. a
Coercion
proving the equality.
In the rewriting stage, type-checking plugins have access to the rewriter
environment RewriteEnv
, which has information about the location of the
type family application, the local type-checking environment, among other things.
Note that a plugin should provide a UniqFM
from TyCon
to rewriting functions,
which specifies a rewriting function for each type family.
Use emptyUFM
or listToUFM
to construct this map,
or import the GHC module GHC.Types.Unique.FM for a more complete API.
askRewriteEnv :: TcPluginM Rewrite RewriteEnv Source #
Ask for the current rewriting environment.
Only available in the rewriter part of the type-checking plugin.
rewriteEnvCtLoc :: RewriteEnv -> CtLoc Source #
Obtain the CtLoc
from a RewriteEnv
.
This can be useful to obtain the location of the constraint currently being rewritten, so that newly emitted constraints can be given the same location information.
data RewriteEnv #
A RewriteEnv
carries the necessary context for performing rewrites
(i.e. type family reductions and following filled-in metavariables)
in the solver.
Arguments
:: String | Name of reduction (for debugging) |
-> Role | Role of reduction ( |
-> [Coercion] | Evidence that this reduction depends on (use |
-> TyCon | Type family |
-> [TcType] | Type family arguments |
-> TcType | The type that the type family application reduces to |
-> Reduction |
Provide a rewriting of a saturated type family application
at the given Role
(Nominal
or Representational
).
The result can be passed to TcPluginRewriteTo
to specify the outcome
of rewriting a type family application.
A Reduction
is the result of an operation that rewrites a type ty_in
.
The Reduction
includes the rewritten type ty_out
and a Coercion
co
such that co :: ty_in ~ ty_out
, where the role of the coercion is determined
by the context. That is, the LHS type of the coercion is the original type
ty_in
, while its RHS type is the rewritten type ty_out
.
A Reduction is always homogeneous, unless it is wrapped inside a HetReduction
,
which separately stores the kind coercion.
See Note [The Reduction type].
Constructors
Reduction | |
Fields |
Instances
Outputable Reduction | |
Defined in GHC.Core.Reduction |
Handling Haskell types
Type variables
newUnique :: MonadTcPlugin m => m Unique Source #
Create a new unique. Useful for generating new variables in the plugin.
newFlexiTyVar :: MonadTcPlugin m => Kind -> m TcTyVar Source #
Create a new meta-variable (unification variable) of the given kind.
isTouchableTcPluginM :: MonadTcPlugin m => TcTyVar -> m Bool Source #
Query whether a type variable is touchable:
- is it a unification variable (and not a skolem variable)?
- is it actually unifiable given the current TcLevel
?
mkTyVarTys :: [TyVar] -> [Type] #
Unique identifier.
The type of unique identifiers that are used in many places in GHC
for fast ordering and equality tests. You should generate these with
the functions from the UniqSupply
module
These are sometimes also referred to as "keys" in comments in GHC.
Instances
Show Unique | |
Uniquable Unique | |
Defined in GHC.Types.Unique | |
Outputable Unique | |
Defined in GHC.Types.Unique | |
Eq Unique | |
Type literals (natural numbers, type-level strings)
mkNumLitTy :: Integer -> Type #
isNumLitTy :: Type -> Maybe Integer #
Is this a numeric literal. We also look through type synonyms.
mkStrLitTy :: FastString -> Type #
isStrLitTy :: Type -> Maybe FastString #
Is this a symbol literal. We also look through type synonyms.
Creating and decomposing applications
(mkTyConTy tc) returns (TyConApp tc []) but arranges to share that TyConApp among all calls See Note [Sharing nullary TyConApps] So it's just an alias for tyConNullaryTy!
mkTyConApp :: TyCon -> [Type] -> Type #
splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type]) #
Attempts to tease a type apart into a type constructor and the application of a number of arguments to that constructor
tyConAppTyConPicky_maybe :: Type -> Maybe TyCon #
Retrieve the tycon heading this type, if there is one. Does not look through synonyms.
tyConAppTyCon_maybe :: Type -> Maybe TyCon #
The same as fst . splitTyConApp
We can short-cut the FunTy case
splitAppTy_maybe :: Type -> Maybe (Type, Type) #
Attempt to take a type application apart, whether it is a function, type constructor, or plain type application. Note that type family applications are NEVER unsaturated by this!
splitAppTys :: Type -> (Type, [Type]) #
Recursively splits a type as far as is possible, leaving a residual type being applied to and the type arguments applied to it. Never fails, even if that means returning an empty list of type applications.
Function types
mkVisFunTyMany :: HasDebugCallStack => Type -> Type -> Type infixr 3 #
Make nested arrow types | Special, common, case: Arrow type with mult Many
mkVisFunTysMany :: [Type] -> Type -> Type #
mkInvisFunTy :: HasDebugCallStack => Type -> Type -> Type infixr 3 #
mkInvisFunTys :: HasDebugCallStack => [Type] -> Type -> Type #
mkForAllTy :: ForAllTyBinder -> Type -> Type #
Like mkTyCoForAllTy
, but does not check the occurrence of the binder
See Note [Unused coercion variable in ForAllTy]
mkForAllTys :: [ForAllTyBinder] -> Type -> Type #
Wraps foralls over the type using the provided TyCoVar
s from left to right
mkPiTy :: PiTyBinder -> Type -> Type #
mkPiTys :: [PiTyBinder] -> Type -> Type #
Mult is a type alias for Type.
Mult must contain Type because multiplicity variables are mere type variables (of kind Multiplicity) in Haskell. So the simplest implementation is to make Mult be Type.
Multiplicities can be formed with: - One: GHC.Types.One (= oneDataCon) - Many: GHC.Types.Many (= manyDataCon) - Multiplication: GHC.Types.MultMul (= multMulTyCon)
So that Mult feels a bit more structured, we provide pattern synonyms and smart constructors for these.
Zonking
Zonking is the operation in which GHC actually switches out mutable unification variables for their actual filled in type.
See the Note [What is zonking?] in GHC's source code for more information.
zonkTcType :: MonadTcPluginWork m => TcType -> m TcType Source #
Zonk the given type, which takes the metavariables in the type and substitutes their actual value.
Panicking
It is often better for type-checking plugins to panic when encountering a problem,
as opposed to silently doing something wrong. Use pprPanic
to throw an informative
error message, so that users of your plugin can report an issue if a problem occurs.
panic :: HasCallStack => String -> a #
Panics and asserts.
pprPanic :: HasCallStack => String -> SDoc -> a #
Throw an exception saying "bug in GHC" with a callstack
Map-like data structures based on Unique
s
Import GHC.Types.Unique.FM or GHC.Types.Unique.DFM for
a more complete interface to maps whose keys are Unique
s.
Type of unique deterministic finite maps
The key is just here to keep us honest. It's always safe to use a single type as key. If two types don't overlap in their uniques it's also safe to index the same map at multiple key types. But this is very much discouraged.
Instances
Foldable (UniqDFM key) | Deterministic, in O(n log n). |
Defined in GHC.Types.Unique.DFM Methods fold :: Monoid m => UniqDFM key m -> m # foldMap :: Monoid m => (a -> m) -> UniqDFM key a -> m # foldMap' :: Monoid m => (a -> m) -> UniqDFM key a -> m # foldr :: (a -> b -> b) -> b -> UniqDFM key a -> b # foldr' :: (a -> b -> b) -> b -> UniqDFM key a -> b # foldl :: (b -> a -> b) -> b -> UniqDFM key a -> b # foldl' :: (b -> a -> b) -> b -> UniqDFM key a -> b # foldr1 :: (a -> a -> a) -> UniqDFM key a -> a # foldl1 :: (a -> a -> a) -> UniqDFM key a -> a # toList :: UniqDFM key a -> [a] # null :: UniqDFM key a -> Bool # length :: UniqDFM key a -> Int # elem :: Eq a => a -> UniqDFM key a -> Bool # maximum :: Ord a => UniqDFM key a -> a # minimum :: Ord a => UniqDFM key a -> a # | |
Traversable (UniqDFM key) | Deterministic, in O(n log n). |
Defined in GHC.Types.Unique.DFM | |
Functor (UniqDFM key) | |
Uniquable key => TrieMap (UniqDFM key) | |
Defined in GHC.Data.TrieMap | |
(Data key, Data ele) => Data (UniqDFM key ele) | |
Defined in GHC.Types.Unique.DFM Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> UniqDFM key ele -> c (UniqDFM key ele) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (UniqDFM key ele) # toConstr :: UniqDFM key ele -> Constr # dataTypeOf :: UniqDFM key ele -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (UniqDFM key ele)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (UniqDFM key ele)) # gmapT :: (forall b. Data b => b -> b) -> UniqDFM key ele -> UniqDFM key ele # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UniqDFM key ele -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UniqDFM key ele -> r # gmapQ :: (forall d. Data d => d -> u) -> UniqDFM key ele -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> UniqDFM key ele -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> UniqDFM key ele -> m (UniqDFM key ele) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> UniqDFM key ele -> m (UniqDFM key ele) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> UniqDFM key ele -> m (UniqDFM key ele) # | |
Outputable a => Outputable (UniqDFM key a) | |
Defined in GHC.Types.Unique.DFM | |
type Key (UniqDFM key) | |
Defined in GHC.Data.TrieMap |
lookupUDFM :: Uniquable key => UniqDFM key elt -> key -> Maybe elt #
lookupUDFM_Directly :: UniqDFM key elt -> Unique -> Maybe elt #
A finite map from uniques
of one type to
elements in another type.
The key is just here to keep us honest. It's always safe to use a single type as key. If two types don't overlap in their uniques it's also safe to index the same map at multiple key types. But this is very much discouraged.
Instances
Functor (UniqFM key) | |
(Data key, Data ele) => Data (UniqFM key ele) | |
Defined in GHC.Types.Unique.FM Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> UniqFM key ele -> c (UniqFM key ele) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (UniqFM key ele) # toConstr :: UniqFM key ele -> Constr # dataTypeOf :: UniqFM key ele -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (UniqFM key ele)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (UniqFM key ele)) # gmapT :: (forall b. Data b => b -> b) -> UniqFM key ele -> UniqFM key ele # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UniqFM key ele -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UniqFM key ele -> r # gmapQ :: (forall d. Data d => d -> u) -> UniqFM key ele -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> UniqFM key ele -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> UniqFM key ele -> m (UniqFM key ele) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> UniqFM key ele -> m (UniqFM key ele) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> UniqFM key ele -> m (UniqFM key ele) # | |
Monoid (UniqFM key a) | |
Semigroup (UniqFM key a) | |
Outputable a => Outputable (UniqFM key a) | |
Defined in GHC.Types.Unique.FM | |
Eq ele => Eq (UniqFM key ele) | |
The type-checking environment
getEnvs :: MonadTcPlugin m => m (TcGblEnv, TcLclEnv) Source #
Obtain the current global and local type-checking environments.
Interacting with GHC's constraint solver
Instances
MonadFail TcS | |
Defined in GHC.Tc.Solver.Monad | |
MonadFix TcS | |
Defined in GHC.Tc.Solver.Monad | |
MonadIO TcS | |
Defined in GHC.Tc.Solver.Monad | |
Applicative TcS | |
Functor TcS | |
Monad TcS | |
HasDynFlags TcS | |
Defined in GHC.Tc.Solver.Monad Methods getDynFlags :: TcS DynFlags # | |
MonadThings TcS | |
MonadUnique TcS | |
Defined in GHC.Tc.Solver.Monad | |
HasModule TcS | |
Defined in GHC.Tc.Solver.Monad |
Instances
Outputable InertSet | |
Defined in GHC.Tc.Solver.InertSet |
setInertSet :: InertSet -> TcS () Source #
getTcEvBindsMap :: EvBindsVar -> TcS EvBindMap #
setTcEvBindsMap :: EvBindsVar -> EvBindMap -> TcS () #
Built-in types
This module also re-exports the built-in types that GHC already knows about.
This allows plugins to directly refer to e.g. the promoted data constructor
True
without having to look up its name.
Refer to GHC.Builtin.Names, GHC.Builtin.Types and GHC.Builtin.Types.Prim.
GHC types
These are the types that the plugin will inspect and manipulate.
END OF API DOCUMENTATION, RE-EXPORTS FOLLOW
Some basic types
Instances
Data Boxity | |
Defined in Language.Haskell.Syntax.Basic Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Boxity -> c Boxity # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Boxity # toConstr :: Boxity -> Constr # dataTypeOf :: Boxity -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Boxity) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Boxity) # gmapT :: (forall b. Data b => b -> b) -> Boxity -> Boxity # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Boxity -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Boxity -> r # gmapQ :: (forall d. Data d => d -> u) -> Boxity -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Boxity -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Boxity -> m Boxity # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Boxity -> m Boxity # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Boxity -> m Boxity # | |
Eq Boxity | |
data PromotionFlag #
Is a TyCon a promoted data constructor or just a normal type constructor?
Constructors
NotPromoted | |
IsPromoted |
Instances
Data PromotionFlag | |
Defined in Language.Haskell.Syntax.Type Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> PromotionFlag -> c PromotionFlag # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c PromotionFlag # toConstr :: PromotionFlag -> Constr # dataTypeOf :: PromotionFlag -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c PromotionFlag) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PromotionFlag) # gmapT :: (forall b. Data b => b -> b) -> PromotionFlag -> PromotionFlag # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> PromotionFlag -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> PromotionFlag -> r # gmapQ :: (forall d. Data d => d -> u) -> PromotionFlag -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> PromotionFlag -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> PromotionFlag -> m PromotionFlag # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> PromotionFlag -> m PromotionFlag # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> PromotionFlag -> m PromotionFlag # | |
Eq PromotionFlag | |
Defined in Language.Haskell.Syntax.Type Methods (==) :: PromotionFlag -> PromotionFlag -> Bool # (/=) :: PromotionFlag -> PromotionFlag -> Bool # |
Constructors
BoxedTuple | |
UnboxedTuple | |
ConstraintTuple |
Instances
Data TupleSort | |
Defined in GHC.Types.Basic Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> TupleSort -> c TupleSort # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c TupleSort # toConstr :: TupleSort -> Constr # dataTypeOf :: TupleSort -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c TupleSort) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TupleSort) # gmapT :: (forall b. Data b => b -> b) -> TupleSort -> TupleSort # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TupleSort -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TupleSort -> r # gmapQ :: (forall d. Data d => d -> u) -> TupleSort -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> TupleSort -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> TupleSort -> m TupleSort # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> TupleSort -> m TupleSort # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> TupleSort -> m TupleSort # | |
Binary TupleSort | |
Outputable TupleSort | |
Defined in GHC.Types.Basic | |
Eq TupleSort | |
The number of value arguments that can be applied to a value before it does "real work". So: fib 100 has arity 0 x -> fib x has arity 1 See also Note [Definition of arity] in GHC.Core.Opt.Arity
isPromoted :: PromotionFlag -> Bool #
Names
A unique, unambiguous name for something, containing information about where that thing originated.
Instances
Data Name | |
Defined in GHC.Types.Name Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Name -> c Name # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Name # dataTypeOf :: Name -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Name) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Name) # gmapT :: (forall b. Data b => b -> b) -> Name -> Name # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Name -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Name -> r # gmapQ :: (forall d. Data d => d -> u) -> Name -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Name -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Name -> m Name # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Name -> m Name # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Name -> m Name # | |
NFData Name | |
Defined in GHC.Types.Name | |
NamedThing Name | |
Defined in GHC.Types.Name | |
HasOccName Name | |
Defined in GHC.Types.Name | |
Uniquable Name | |
Defined in GHC.Types.Name | |
Binary Name | Assumes that the |
Outputable Name | |
Defined in GHC.Types.Name | |
OutputableBndr Name | |
Defined in GHC.Types.Name Methods pprBndr :: BindingSite -> Name -> SDoc # pprPrefixOcc :: Name -> SDoc # pprInfixOcc :: Name -> SDoc # bndrIsJoin_maybe :: Name -> Maybe Int # | |
Eq Name | |
Ord Name | Caution: This instance is implemented via See |
type Anno Name | |
Defined in GHC.Hs.Extension | |
type Anno (LocatedN Name) | |
Defined in GHC.Hs.Binds | |
type Anno [LocatedN Name] | |
Defined in GHC.Hs.Binds |
Occurrence Name
In this context that means: "classified (i.e. as a type name, value name, etc) but not qualified and not yet resolved"
Instances
Data OccName | |
Defined in GHC.Types.Name.Occurrence Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> OccName -> c OccName # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c OccName # toConstr :: OccName -> Constr # dataTypeOf :: OccName -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c OccName) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OccName) # gmapT :: (forall b. Data b => b -> b) -> OccName -> OccName # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> OccName -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> OccName -> r # gmapQ :: (forall d. Data d => d -> u) -> OccName -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> OccName -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> OccName -> m OccName # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> OccName -> m OccName # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> OccName -> m OccName # | |
NFData OccName | |
Defined in GHC.Types.Name.Occurrence | |
HasOccName OccName | |
Defined in GHC.Types.Name.Occurrence | |
Uniquable OccName | |
Defined in GHC.Types.Name.Occurrence | |
Binary OccName | |
Outputable OccName | |
Defined in GHC.Types.Name.Occurrence | |
OutputableBndr OccName | |
Defined in GHC.Types.Name.Occurrence Methods pprBndr :: BindingSite -> OccName -> SDoc # pprPrefixOcc :: OccName -> SDoc # pprInfixOcc :: OccName -> SDoc # bndrIsJoin_maybe :: OccName -> Maybe Int # | |
Eq OccName | |
Ord OccName | |
Defined in GHC.Types.Name.Occurrence |
A global typecheckable-thing, essentially anything that has a name.
Not to be confused with a TcTyThing
, which is also a typecheckable
thing but in the *local* context. See GHC.Tc.Utils.Env for how to retrieve
a TyThing
given a Name
.
Instances
NamedThing TyThing | |
Defined in GHC.Types.TyThing | |
Outputable TyThing | |
Defined in GHC.Types.TyThing |
A typecheckable thing available in a local context. Could be
AGlobal
TyThing
, but also lexically scoped variables, etc.
See GHC.Tc.Utils.Env for how to retrieve a TyThing
given a Name
.
Instances
Outputable TcTyThing | |
Defined in GHC.Tc.Types |
class Monad m => MonadThings (m :: Type -> Type) where #
Class that abstracts out the common ability of the monads in GHC
to lookup a TyThing
in the monadic environment by Name
. Provides
a number of related convenience functions for accessing particular
kinds of TyThing
Minimal complete definition
Methods
lookupThing :: Name -> m TyThing #
lookupDataCon :: Name -> m DataCon #
lookupTyCon :: Name -> m TyCon #
Instances
MonadThings TcS | |
(Monad (TcPluginM s), MonadTcPlugin (TcPluginM s)) => MonadThings (TcPluginM s) Source # | |
MonadThings m => MonadThings (ReaderT s m) | |
Instances
Data Class | |
Defined in GHC.Core.Class Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Class -> c Class # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Class # dataTypeOf :: Class -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Class) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Class) # gmapT :: (forall b. Data b => b -> b) -> Class -> Class # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Class -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Class -> r # gmapQ :: (forall d. Data d => d -> u) -> Class -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Class -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Class -> m Class # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Class -> m Class # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Class -> m Class # | |
NamedThing Class | |
Defined in GHC.Core.Class | |
Uniquable Class | |
Defined in GHC.Core.Class | |
Outputable Class | |
Defined in GHC.Core.Class | |
Eq Class | |
Lookupable Class Source # | |
A data constructor
Instances
Data DataCon | |
Defined in GHC.Core.DataCon Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> DataCon -> c DataCon # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c DataCon # toConstr :: DataCon -> Constr # dataTypeOf :: DataCon -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c DataCon) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DataCon) # gmapT :: (forall b. Data b => b -> b) -> DataCon -> DataCon # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> DataCon -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> DataCon -> r # gmapQ :: (forall d. Data d => d -> u) -> DataCon -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> DataCon -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> DataCon -> m DataCon # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> DataCon -> m DataCon # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> DataCon -> m DataCon # | |
NamedThing DataCon | |
Defined in GHC.Core.DataCon | |
Uniquable DataCon | |
Defined in GHC.Core.DataCon | |
Outputable DataCon | |
Defined in GHC.Core.DataCon | |
OutputableBndr DataCon | |
Defined in GHC.Core.DataCon Methods pprBndr :: BindingSite -> DataCon -> SDoc # pprPrefixOcc :: DataCon -> SDoc # pprInfixOcc :: DataCon -> SDoc # bndrIsJoin_maybe :: DataCon -> Maybe Int # | |
Eq DataCon | |
Lookupable DataCon Source # | |
Lookupable (Promoted DataCon) Source # | |
TyCons represent type constructors. Type constructors are introduced by things such as:
1) Data declarations: data Foo = ...
creates the Foo
type constructor of
kind *
2) Type synonyms: type Foo = ...
creates the Foo
type constructor
3) Newtypes: newtype Foo a = MkFoo ...
creates the Foo
type constructor
of kind * -> *
4) Class declarations: class Foo where
creates the Foo
type constructor
of kind *
This data type also encodes a number of primitive, built in type constructors such as those for function and tuple types.
If you edit this type, you may need to update the GHC formalism See Note [GHC Formalism] in GHC.Core.Lint
Instances
Data TyCon | |
Defined in GHC.Core.TyCon Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> TyCon -> c TyCon # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c TyCon # dataTypeOf :: TyCon -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c TyCon) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyCon) # gmapT :: (forall b. Data b => b -> b) -> TyCon -> TyCon # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TyCon -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TyCon -> r # gmapQ :: (forall d. Data d => d -> u) -> TyCon -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> TyCon -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> TyCon -> m TyCon # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> TyCon -> m TyCon # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> TyCon -> m TyCon # | |
NamedThing TyCon | |
Defined in GHC.Core.TyCon | |
Uniquable TyCon | |
Defined in GHC.Core.TyCon | |
Outputable TyCon | |
Defined in GHC.Core.TyCon | |
Eq TyCon | |
Lookupable TyCon Source # | |
data FastString #
A FastString
is a UTF-8 encoded string together with a unique ID. All
FastString
s are stored in a global hashtable to support fast O(1)
comparison.
It is also associated with a lazy reference to the Z-encoding of this string which is used by the compiler internally.
Instances
Constraints
A choice of equality relation. This is separate from the type Role
because Phantom
does not define a (non-trivial) equality relation.
Instances
Outputable EqRel | |
Defined in GHC.Core.Predicate | |
Eq EqRel | |
Ord EqRel | |
Instances
Outputable Ct | |
Defined in GHC.Tc.Types.Constraint |
data CtEvidence #
Instances
Outputable CtEvidence | |
Defined in GHC.Tc.Types.Constraint Methods ppr :: CtEvidence -> SDoc # |
Instances
Outputable CtOrigin | |
Defined in GHC.Tc.Types.Origin |
Instances
Outputable QCInst | |
Defined in GHC.Tc.Types.Constraint |
Instances
Data Type | |
Defined in GHC.Core.TyCo.Rep Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Type -> c Type # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Type # dataTypeOf :: Type -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Type) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Type) # gmapT :: (forall b. Data b => b -> b) -> Type -> Type # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r # gmapQ :: (forall d. Data d => d -> u) -> Type -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Type -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Type -> m Type # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Type -> m Type # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Type -> m Type # | |
Outputable Type | |
Defined in GHC.Core.TyCo.Rep |
A type of the form p
of constraint kind represents a value whose type is
the Haskell predicate p
, where a predicate is what occurs before
the =>
in a Haskell type.
We use PredType
as documentation to mark those types that we guarantee to
have this kind.
It can be expanded into its representation, but:
- The type checker must treat it as opaque
- The rest of the compiler treats it as transparent
Consider these examples:
f :: (Eq a) => a -> Int g :: (?x :: Int -> Int) => a -> Int h :: (r\l) => {r} => {l::Int | r}
Here the Eq a
and ?x :: Int -> Int
and rl
are all called "predicates"
InstEnvs
represents the combination of the global type class instance
environment, the local type class instance environment, and the set of
transitively reachable orphan modules (according to what modules have been
directly imported) used to test orphan instance visibility.
Instances
Outputable TcLevel | |
Defined in GHC.Tc.Utils.TcType | |
Eq TcLevel | |
Ord TcLevel | |
Coercions and evidence
A Coercion
is concrete evidence of the equality/convertibility
of two types.
Instances
Data Coercion | |
Defined in GHC.Core.TyCo.Rep Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Coercion -> c Coercion # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Coercion # toConstr :: Coercion -> Constr # dataTypeOf :: Coercion -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Coercion) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Coercion) # gmapT :: (forall b. Data b => b -> b) -> Coercion -> Coercion # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Coercion -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Coercion -> r # gmapQ :: (forall d. Data d => d -> u) -> Coercion -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Coercion -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Coercion -> m Coercion # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Coercion -> m Coercion # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Coercion -> m Coercion # | |
Outputable Coercion | |
Defined in GHC.Core.TyCo.Rep |
See Note [Roles] in GHC.Core.Coercion
Order of constructors matters: the Ord instance coincides with the *super*typing relation on roles.
Constructors
Nominal | |
Representational | |
Phantom |
Instances
Data Role | |
Defined in Language.Haskell.Syntax.Basic Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Role -> c Role # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Role # dataTypeOf :: Role -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Role) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Role) # gmapT :: (forall b. Data b => b -> b) -> Role -> Role # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Role -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Role -> r # gmapQ :: (forall d. Data d => d -> u) -> Role -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Role -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Role -> m Role # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Role -> m Role # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Role -> m Role # | |
Eq Role | |
Ord Role | |
type Anno (Maybe Role) | |
type Anno (Maybe Role) | |
data UnivCoProvenance #
For simplicity, we have just one UnivCo that represents a coercion from
some type to some other type, with (in general) no restrictions on the
type. The UnivCoProvenance specifies more exactly what the coercion really
is and why a program should (or shouldn't!) trust the coercion.
It is reasonable to consider each constructor of UnivCoProvenance
as a totally independent coercion form; their only commonality is
that they don't tell you what types they coercion between. (That info
is in the UnivCo
constructor of Coercion
.
Instances
Data UnivCoProvenance | |
Defined in GHC.Core.TyCo.Rep Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> UnivCoProvenance -> c UnivCoProvenance # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c UnivCoProvenance # toConstr :: UnivCoProvenance -> Constr # dataTypeOf :: UnivCoProvenance -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c UnivCoProvenance) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnivCoProvenance) # gmapT :: (forall b. Data b => b -> b) -> UnivCoProvenance -> UnivCoProvenance # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r # gmapQ :: (forall d. Data d => d -> u) -> UnivCoProvenance -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> UnivCoProvenance -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> UnivCoProvenance -> m UnivCoProvenance # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> UnivCoProvenance -> m UnivCoProvenance # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> UnivCoProvenance -> m UnivCoProvenance # | |
Outputable UnivCoProvenance | |
Defined in GHC.Core.TyCo.Rep Methods ppr :: UnivCoProvenance -> SDoc # |
data CoercionHole #
A coercion to be filled in by the type-checker. See Note [Coercion holes]
Instances
Data CoercionHole | |
Defined in GHC.Core.TyCo.Rep Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> CoercionHole -> c CoercionHole # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c CoercionHole # toConstr :: CoercionHole -> Constr # dataTypeOf :: CoercionHole -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c CoercionHole) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CoercionHole) # gmapT :: (forall b. Data b => b -> b) -> CoercionHole -> CoercionHole # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> CoercionHole -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> CoercionHole -> r # gmapQ :: (forall d. Data d => d -> u) -> CoercionHole -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> CoercionHole -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> CoercionHole -> m CoercionHole # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> CoercionHole -> m CoercionHole # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> CoercionHole -> m CoercionHole # | |
Uniquable CoercionHole | |
Defined in GHC.Core.TyCo.Rep Methods getUnique :: CoercionHole -> Unique # | |
Outputable CoercionHole | |
Defined in GHC.Core.TyCo.Rep Methods ppr :: CoercionHole -> SDoc # |
Instances
Outputable EvBind | |
Defined in GHC.Tc.Types.Evidence |
Instances
Data EvTerm | |
Defined in GHC.Tc.Types.Evidence Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> EvTerm -> c EvTerm # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c EvTerm # toConstr :: EvTerm -> Constr # dataTypeOf :: EvTerm -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c EvTerm) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c EvTerm) # gmapT :: (forall b. Data b => b -> b) -> EvTerm -> EvTerm # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> EvTerm -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> EvTerm -> r # gmapQ :: (forall d. Data d => d -> u) -> EvTerm -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> EvTerm -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> EvTerm -> m EvTerm # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> EvTerm -> m EvTerm # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> EvTerm -> m EvTerm # | |
Outputable EvTerm | |
Defined in GHC.Tc.Types.Evidence |
data EvBindsVar #
Instances
Uniquable EvBindsVar | |
Defined in GHC.Tc.Types.Evidence Methods getUnique :: EvBindsVar -> Unique # | |
Outputable EvBindsVar | |
Defined in GHC.Tc.Types.Evidence Methods ppr :: EvBindsVar -> SDoc # |
This is the data type that represents GHCs core intermediate language. Currently GHC uses System FC https://www.microsoft.com/en-us/research/publication/system-f-with-type-equality-coercions/ for this purpose, which is closely related to the simpler and better known System F http://en.wikipedia.org/wiki/System_F.
We get from Haskell source to this Core language in a number of stages:
- The source code is parsed into an abstract syntax tree, which is represented
by the data type
HsExpr
with the names beingRdrNames
- This syntax tree is renamed, which attaches a
Unique
to everyRdrName
(yielding aName
) to disambiguate identifiers which are lexically identical. For example, this program:
f x = let f x = x + 1 in f (x - 2)
Would be renamed by having Unique
s attached so it looked something like this:
f_1 x_2 = let f_3 x_4 = x_4 + 1 in f_3 (x_2 - 2)
But see Note [Shadowing] below.
- The resulting syntax tree undergoes type checking (which also deals with instantiating
type class arguments) to yield a
HsExpr
type that hasId
as it's names. - Finally the syntax tree is desugared from the expressive
HsExpr
type into thisExpr
type, which has far fewer constructors and hence is easier to perform optimization, analysis and code generation on.
The type parameter b
is for the type of binders in the expression tree.
The language consists of the following elements:
- Variables See Note [Variable occurrences in Core]
- Primitive literals
- Applications: note that the argument may be a
Type
. See Note [Representation polymorphism invariants] - Lambda abstraction See Note [Representation polymorphism invariants]
- Recursive and non recursive
let
s. Operationally this corresponds to allocating a thunk for the things bound and then executing the sub-expression.
See Note [Core letrec invariant] See Note [Core let-can-float invariant] See Note [Representation polymorphism invariants] See Note [Core type and coercion invariant]
- Case expression. Operationally this corresponds to evaluating the scrutinee (expression examined) to weak head normal form and then examining at most one level of resulting constructor (i.e. you cannot do nested pattern matching directly with this).
The binder gets bound to the value of the scrutinee,
and the Type
must be that of all the case alternatives
IMPORTANT: see Note [Case expression invariants]
- Cast an expression to a particular type.
This is used to implement
newtype
s (anewtype
constructor or destructor just becomes aCast
in Core) and GADTs. - Ticks. These are used to represent all the source annotation we support: profiling SCCs, HPC ticks, and GHCi breakpoints.
- A type: this should only show up at the top level of an Arg
- A coercion
Instances
Data b => Data (Expr b) | |
Defined in GHC.Core Methods gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Expr b -> c (Expr b) # gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Expr b) # toConstr :: Expr b -> Constr # dataTypeOf :: Expr b -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Expr b)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Expr b)) # gmapT :: (forall b0. Data b0 => b0 -> b0) -> Expr b -> Expr b # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Expr b -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Expr b -> r # gmapQ :: (forall d. Data d => d -> u) -> Expr b -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Expr b -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Expr b -> m (Expr b) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Expr b -> m (Expr b) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Expr b -> m (Expr b) # |
The common case for the type of binders and variables when we are manipulating the Core language within GHC
A place for type-checking evidence to go after it is generated.
- Wanted equalities use HoleDest,
- other Wanteds use EvVarDest.
Constructors
EvVarDest EvVar | bind this var to the evidence EvVarDest is always used for non-type-equalities e.g. class constraints |
HoleDest CoercionHole | fill in this hole with the evidence HoleDest is always used for type-equalities See Note [Coercion holes] in GHC.Core.TyCo.Rep |
Instances
Outputable TcEvDest | |
Defined in GHC.Tc.Types.Constraint |
The type-checking environment
TcGblEnv
describes the top-level of the module at the
point at which the typechecker is finished work.
It is this structure that is handed on to the desugarer
For state that needs to be updated during the typechecking
phase and returned at end, use a TcRef
(= IORef
).
Instances
ContainsModule TcGblEnv | |
Defined in GHC.Tc.Types Methods extractModule :: TcGblEnv -> Module # |
Source locations
data GenLocated l e #
We attach SrcSpans to lots of things, so let's have a datatype for it.
Constructors
L l e |
Instances
type Located = GenLocated SrcSpan #
type RealLocated = GenLocated RealSrcSpan #
unLoc :: GenLocated l e -> e #
getLoc :: GenLocated l e -> l #
Pretty-printing
Represents a pretty-printable document.
To display an SDoc
, use printSDoc
, printSDocLn
, bufLeftRenderSDoc
,
or renderWithContext
. Avoid calling runSDoc
directly as it breaks the
abstraction layer.
Instances
IsString SDoc | |
Defined in GHC.Utils.Outputable Methods fromString :: String -> SDoc # | |
IsDoc SDoc | |
IsLine SDoc | |
IsOutput SDoc | |
Defined in GHC.Utils.Outputable | |
Outputable SDoc | |
Defined in GHC.Utils.Outputable | |
OutputableP env SDoc | |
Defined in GHC.Utils.Outputable | |
type Line SDoc | |
Defined in GHC.Utils.Outputable |
class Outputable a where #
Class designating that some type has an SDoc
representation