content: -- | This module provides an interface for typechecker plugins to
  -- access select functions of the 'TcM', principally those to do with
  -- reading parts of the state.
  {-# LANGUAGE CPP #-}
  
  module Eta.TypeCheck.TcPluginM (
  #ifdef ETA_REPL
          -- * Basic TcPluginM functionality
          TcPluginM,
          tcPluginIO,
          tcPluginTrace,
          unsafeTcPluginTcM,
  
          -- * Finding Modules and Names
          FindResult(..),
          findImportedModule,
          lookupOrig,
  
          -- * Looking up Names in the typechecking environment
          tcLookupGlobal,
          tcLookupTyCon,
          tcLookupDataCon,
          tcLookupClass,
          tcLookup,
          tcLookupId,
  
          -- * Getting the TcM state
          getTopEnv,
          getEnvs,
          getInstEnvs,
          getFamInstEnvs,
          matchFam,
  
          -- * Type variables
          newFlexiTyVar,
          isTouchableTcPluginM,
  
          -- * Zonking
          zonkTcType,
          zonkCt
  #endif
      ) where
  
  #ifdef ETA_REPL
  import qualified Eta.TypeCheck.TcRnMonad as TcRnMonad
  import qualified Eta.TypeCheck.TcSMonad as TcSMonad
  import qualified Eta.TypeCheck.TcEnv as TcEnv
  import qualified Eta.TypeCheck.TcMType as TcMType
  import qualified Eta.TypeCheck.Inst as Inst
  import qualified Eta.TypeCheck.FamInst as FamInst
  import qualified Eta.Iface.IfaceEnv as IfaceEnv
  import qualified Eta.Main.Finder as Finder
  
  import Eta.Types.FamInstEnv ( FamInstEnv )
  import Eta.TypeCheck.TcRnMonad  ( TcGblEnv, TcLclEnv, Ct, TcPluginM
                    , unsafeTcPluginTcM, liftIO, traceTc )
  import Eta.TypeCheck.TcMType    ( TcTyVar, TcType )
  import Eta.TypeCheck.TcEnv      ( TcTyThing )
  import Eta.TypeCheck.TcEvidence ( TcCoercion )
  
  import Eta.BasicTypes.Module
  import Eta.BasicTypes.Name
  import Eta.Types.TyCon
  import Eta.BasicTypes.DataCon
  import Eta.Types.Class
  import Eta.Main.HscTypes
  import Eta.Utils.Outputable
  import Eta.Types.Type
  import Eta.BasicTypes.Id
  import Eta.Types.InstEnv
  import Eta.Utils.FastString
  
  
  -- | Perform some IO, typically to interact with an external tool.
  tcPluginIO :: IO a -> TcPluginM a
  tcPluginIO a = unsafeTcPluginTcM (liftIO a)
  
  -- | Output useful for debugging the compiler.
  tcPluginTrace :: String -> SDoc -> TcPluginM ()
  tcPluginTrace a b = unsafeTcPluginTcM (traceTc a b)
  
  
  findImportedModule :: ModuleName -> Maybe FastString -> TcPluginM FindResult
  findImportedModule mod_name mb_pkg = do
      hsc_env <- getTopEnv
      tcPluginIO $ Finder.findImportedModule hsc_env mod_name mb_pkg
  
  lookupOrig :: Module -> OccName -> TcPluginM Name
  lookupOrig mod = unsafeTcPluginTcM . IfaceEnv.lookupOrig mod
  
  
  tcLookupGlobal :: Name -> TcPluginM TyThing
  tcLookupGlobal = unsafeTcPluginTcM . TcEnv.tcLookupGlobal
  
  tcLookupTyCon :: Name -> TcPluginM TyCon
  tcLookupTyCon = unsafeTcPluginTcM . TcEnv.tcLookupTyCon
  
  tcLookupDataCon :: Name -> TcPluginM DataCon
  tcLookupDataCon = unsafeTcPluginTcM . TcEnv.tcLookupDataCon
  
  tcLookupClass :: Name -> TcPluginM Class
  tcLookupClass = unsafeTcPluginTcM . TcEnv.tcLookupClass
  
  tcLookup :: Name -> TcPluginM TcTyThing
  tcLookup = unsafeTcPluginTcM . TcEnv.tcLookup
  
  tcLookupId :: Name -> TcPluginM Id
  tcLookupId = unsafeTcPluginTcM . TcEnv.tcLookupId
  
  
  getTopEnv :: TcPluginM HscEnv
  getTopEnv = unsafeTcPluginTcM TcRnMonad.getTopEnv
  
  getEnvs :: TcPluginM (TcGblEnv, TcLclEnv)
  getEnvs = unsafeTcPluginTcM TcRnMonad.getEnvs
  
  getInstEnvs :: TcPluginM InstEnvs
  getInstEnvs = unsafeTcPluginTcM Inst.tcGetInstEnvs
  
  getFamInstEnvs :: TcPluginM (FamInstEnv, FamInstEnv)
  getFamInstEnvs = unsafeTcPluginTcM FamInst.tcGetFamInstEnvs
  
  matchFam :: TyCon -> [Type] -> TcPluginM (Maybe (TcCoercion, TcType))
  matchFam tycon args = unsafeTcPluginTcM $ TcSMonad.matchFamTcM tycon args
  
  
  newFlexiTyVar :: Kind -> TcPluginM TcTyVar
  newFlexiTyVar = unsafeTcPluginTcM . TcMType.newFlexiTyVar
  
  isTouchableTcPluginM :: TcTyVar -> TcPluginM Bool
  isTouchableTcPluginM = unsafeTcPluginTcM . TcRnMonad.isTouchableTcM
  
  
  zonkTcType :: TcType -> TcPluginM TcType
  zonkTcType = unsafeTcPluginTcM . TcMType.zonkTcType
  
  zonkCt :: Ct -> TcPluginM Ct
  zonkCt = unsafeTcPluginTcM . TcMType.zonkCt
  #endif
  