{-# LANGUAGE CPP, FlexibleInstances, PatternGuards, PatternSynonyms #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances, ViewPatterns                     #-}
{-# LANGUAGE PatternSynonyms #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module GHC.TypeLits.Presburger.Compat (module GHC.TypeLits.Presburger.Compat) where
import Data.Function       (on)
import GHC.TcPluginM.Extra as GHC.TypeLits.Presburger.Compat (evByFiat, lookupModule, lookupName,
                                          tracePlugin)
import Data.Generics.Twins

#if MIN_VERSION_ghc(9,0,0)
import GHC.Builtin.Names as GHC.TypeLits.Presburger.Compat (gHC_TYPENATS, dATA_TYPE_EQUALITY)
import qualified GHC.Builtin.Names as Old
import GHC.Hs as GHC.TypeLits.Presburger.Compat (HsModule(..), NoExtField(..))
import GHC.Hs.ImpExp as GHC.TypeLits.Presburger.Compat (ImportDecl(..), ImportDeclQualifiedStyle(..))
import GHC.Hs.Extension as GHC.TypeLits.Presburger.Compat (GhcPs)
import GHC.Builtin.Types as GHC.TypeLits.Presburger.Compat
  ( boolTyCon,
    eqTyConName,
    promotedEQDataCon,
    promotedGTDataCon,
    promotedLTDataCon,
  )
import qualified GHC.Builtin.Types as TysWiredIn
import GHC.Builtin.Types.Literals as GHC.TypeLits.Presburger.Compat
import GHC.Core.Class as GHC.TypeLits.Presburger.Compat (className, classTyCon)
import GHC.Core.FamInstEnv as GHC.TypeLits.Presburger.Compat
import GHC.Core.Predicate as GHC.TypeLits.Presburger.Compat (EqRel (..), Pred (..), isEqPred, mkPrimEqPredRole)
import qualified GHC.Core.Predicate as Old (classifyPredType)
import GHC.Core.TyCo.Rep as GHC.TypeLits.Presburger.Compat (TyLit (NumTyLit), Type (..))
import GHC.Core.TyCon as GHC.TypeLits.Presburger.Compat
import qualified GHC.Core.Type as Old
import GHC.Core.Unify as Old (tcUnifyTy)
import GHC.Unit.Types (Module, UnitId, toUnitId)
import GHC.Unit.Types as GHC.TypeLits.Presburger.Compat (mkModule)
import GHC.Data.FastString as GHC.TypeLits.Presburger.Compat (FastString, fsLit, unpackFS)
#if MIN_VERSION_ghc(9,2,0)
import GHC.Driver.Env.Types as GHC.TypeLits.Presburger.Compat (HscEnv (hsc_dflags))
#else
import GHC.Driver.Types as GHC.TypeLits.Presburger.Compat (HscEnv (hsc_dflags))
import GHC.Driver.Session (unitState)
#endif
import GHC.Plugins (InScopeSet, Outputable, emptyUFM, moduleUnit, Unit, Name)
#if MIN_VERSION_ghc(9,2,0)
import GHC.Hs as GHC.TypeLits.Presburger.Compat (HsParsedModule(..))
import GHC.Types.TyThing as GHC.TypeLits.Presburger.Compat (lookupTyCon)
import GHC.Builtin.Types (naturalTy)
#else
import GHC.Plugins as GHC.TypeLits.Presburger.Compat 
  ( HsParsedModule(..),
    lookupTyCon,
    typeNatKind
  )
#endif

import GHC.Plugins as GHC.TypeLits.Presburger.Compat
  ( PackageName (..),isStrLitTy, isNumLitTy,
    nilDataCon, consDataCon,
    Hsc,
    Plugin (..),
    TCvSubst (..),
    TvSubstEnv,
    TyVar,
    defaultPlugin,
    emptyTCvSubst,
    eqType,
    mkTcOcc,
    mkTyConTy,
    mkTyVarTy,
    ppr,
    promotedFalseDataCon,
    promotedTrueDataCon,
    purePlugin,
    splitTyConApp,
    splitTyConApp_maybe,
    text,
    tyConAppTyCon_maybe,
    typeKind,
    unionTCvSubst,
  )
import GHC.Tc.Plugin (lookupOrig)
import GHC.Core.InstEnv as GHC.TypeLits.Presburger.Compat (classInstances)
#if MIN_VERSION_ghc(9,2,0)
import GHC.Tc.Plugin (unsafeTcPluginTcM)
import GHC.Utils.Logger (getLogger)
import Data.Functor ((<&>))
import GHC.Unit.Types as GHC.TypeLits.Presburger.Compat (IsBootInterface(..))
#else
import GHC.Driver.Types as GHC.TypeLits.Presburger.Compat (IsBootInterface(..))
#endif

import GHC.Tc.Plugin as GHC.TypeLits.Presburger.Compat
  ( TcPluginM,
    getInstEnvs,
    newFlexiTyVar,
    getTopEnv,
    lookupOrig,
    newFlexiTyVar,
    newWanted,
    matchFam,
    tcLookupClass,
    tcLookupTyCon,
    tcPluginIO,
    tcPluginTrace,
  )
import GHC.Tc.Types as GHC.TypeLits.Presburger.Compat (TcPlugin (..), TcPluginResult (..))
import GHC.Tc.Types.Constraint as GHC.TypeLits.Presburger.Compat
  ( Ct,
    CtEvidence,
    ctEvPred,
    ctEvidence,
    isWanted,
  )
import GHC.Tc.Types.Evidence as GHC.TypeLits.Presburger.Compat (EvTerm)
import GHC.Tc.Utils.TcType (TcTyVar, TcType)
import GHC.Tc.Utils.TcType as GHC.TypeLits.Presburger.Compat (tcTyFamInsts)
import qualified GHC.TcPluginM.Extra as Extra
import GHC.Types.Name.Occurrence as GHC.TypeLits.Presburger.Compat (emptyOccSet, mkInstTyTcOcc)
import GHC.Types.Unique as GHC.TypeLits.Presburger.Compat (getKey, getUnique)
import GHC.Unit.Module as GHC.TypeLits.Presburger.Compat (ModuleName, mkModuleName)
import GHC.Unit.State as GHC.TypeLits.Presburger.Compat (lookupPackageName)
import GHC.Unit.State (initUnits, UnitState (preloadUnits))
import GHC.Unit.Types (UnitId(..), fsToUnit, toUnitId)
import GHC.Utils.Outputable as GHC.TypeLits.Presburger.Compat (showSDocUnsafe)
-- GHC 9 Ends HERE
#else
import Class as GHC.TypeLits.Presburger.Compat (classTyCon, className)
import FastString as GHC.TypeLits.Presburger.Compat (FastString, fsLit, unpackFS)
import GhcPlugins (InScopeSet, Outputable, emptyUFM, InstalledUnitId(..), initPackages, Name)
import GhcPlugins as GHC.TypeLits.Presburger.Compat (PackageName (..), fsToUnitId, lookupPackageName, lookupTyCon, mkTcOcc, mkTyConTy, ppr, promotedFalseDataCon, promotedTrueDataCon, text, tyConAppTyCon_maybe, typeKind, typeNatKind)
import HscTypes as GHC.TypeLits.Presburger.Compat (HscEnv (hsc_dflags))
import Module as GHC.TypeLits.Presburger.Compat (ModuleName, mkModuleName, mkModule)
import Module (Module, UnitId)
import OccName as GHC.TypeLits.Presburger.Compat (emptyOccSet, mkInstTyTcOcc)
import Outputable as GHC.TypeLits.Presburger.Compat (showSDocUnsafe)
import Plugins as GHC.TypeLits.Presburger.Compat (Plugin (..), defaultPlugin)
import PrelNames as GHC.TypeLits.Presburger.Compat (gHC_TYPENATS, dATA_TYPE_EQUALITY)
import qualified PrelNames as Old
import TcEvidence as GHC.TypeLits.Presburger.Compat (EvTerm)
import TcHsType as GHC.TypeLits.Presburger.Compat (tcInferApps)
import TcPluginM as GHC.TypeLits.Presburger.Compat
  ( TcPluginM,
    getTopEnv,
    lookupOrig,
    matchFam,
    newFlexiTyVar,
    newWanted,
    tcLookupClass,
    tcLookupTyCon,
    tcPluginIO,
    tcPluginTrace,
  )
import TcRnMonad as GHC.TypeLits.Presburger.Compat (TcPluginResult (..))
import TcRnTypes as GHC.TypeLits.Presburger.Compat (TcPlugin (..))
import TcType as GHC.TypeLits.Presburger.Compat (tcTyFamInsts)
import TcTypeNats as GHC.TypeLits.Presburger.Compat
import TyCoRep ()
import TyCoRep as GHC.TypeLits.Presburger.Compat (TyLit (NumTyLit), Type (..))
import TyCon as GHC.TypeLits.Presburger.Compat
import Type as GHC.TypeLits.Presburger.Compat (TCvSubst (..), TvSubstEnv, emptyTCvSubst, eqType, mkTyVarTy, splitTyConApp, splitTyConApp_maybe, unionTCvSubst)
import qualified Type as Old
import TysWiredIn as GHC.TypeLits.Presburger.Compat
  ( boolTyCon,
    promotedEQDataCon,
    promotedGTDataCon,
    promotedLTDataCon,
  )
import Unify as Old (tcUnifyTy)
import Unique as GHC.TypeLits.Presburger.Compat (getKey, getUnique)
import Var as GHC.TypeLits.Presburger.Compat (TyVar)
-- Conditional imports for GHC <9
#if MIN_VERSION_ghc(8,4,1)
import TcType (TcTyVar, TcType)
import qualified GHC.TcPluginM.Extra as Extra
import qualified GHC
#else
import Data.Maybe
import TcPluginM (zonkCt)
import TcRnTypes (cc_ev, ctev_pred)
#endif
#if MIN_VERSION_ghc(8,6,0)
import Plugins as GHC.TypeLits.Presburger.Compat (purePlugin)
#endif
#if MIN_VERSION_ghc(8,8,1)
import Name
import TysWiredIn as GHC.TypeLits.Presburger.Compat (eqTyConName) 
import qualified TysWiredIn
#else
import PrelNames as GHC.TypeLits.Presburger.Compat (eqTyConName) 
#endif

#if MIN_VERSION_ghc(8,10,1)
import Predicate as GHC.TypeLits.Presburger.Compat (EqRel (..), Pred(..))
import Predicate as GHC.TypeLits.Presburger.Compat (isEqPred)
import GHC (NoExtField(..))
import qualified Predicate as Old (classifyPredType)
import Predicate as GHC.TypeLits.Presburger.Compat  (mkPrimEqPredRole)
import Constraint as GHC.TypeLits.Presburger.Compat 
    (Ct, ctEvidence, CtEvidence, ctEvPred, isWanted)
#else
import GHC (NoExt(..))
import GhcPlugins as GHC.TypeLits.Presburger.Compat (EqRel (..), PredTree (..))
import GhcPlugins as GHC.TypeLits.Presburger.Compat (isEqPred)
import qualified GhcPlugins as Old (classifyPredType)
import TcRnMonad as GHC.TypeLits.Presburger.Compat (Ct, isWanted)
import Type      as GHC.TypeLits.Presburger.Compat (mkPrimEqPredRole)
import TcRnTypes as GHC.TypeLits.Presburger.Compat (ctEvPred, ctEvidence)
#endif
#endif

#if MIN_VERSION_ghc(8,10,1)
type PredTree = Pred
#endif


#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
data TvSubst = TvSubst InScopeSet TvSubstEnv

instance Outputable  TvSubst where
  ppr :: TvSubst -> SDoc
ppr = TCvSubst -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TCvSubst -> SDoc) -> (TvSubst -> TCvSubst) -> TvSubst -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TvSubst -> TCvSubst
toTCv

emptyTvSubst :: TvSubst
emptyTvSubst :: TvSubst
emptyTvSubst = case TCvSubst
emptyTCvSubst of
  TCvSubst InScopeSet
set TvSubstEnv
tvsenv CvSubstEnv
_ -> InScopeSet -> TvSubstEnv -> TvSubst
TvSubst InScopeSet
set TvSubstEnv
tvsenv

toTCv :: TvSubst -> TCvSubst
toTCv :: TvSubst -> TCvSubst
toTCv (TvSubst InScopeSet
set TvSubstEnv
tvenv) = InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
set TvSubstEnv
tvenv CvSubstEnv
forall elt. UniqFM elt
emptyUFM

substTy :: TvSubst -> Type -> Type
substTy :: TvSubst -> Type -> Type
substTy TvSubst
tvs = HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
Old.substTy (TvSubst -> TCvSubst
toTCv TvSubst
tvs)

unionTvSubst :: TvSubst -> TvSubst -> TvSubst
unionTvSubst :: TvSubst -> TvSubst -> TvSubst
unionTvSubst TvSubst
s1 TvSubst
s2 =
  TCvSubst -> TvSubst
fromTCv (TCvSubst -> TvSubst) -> TCvSubst -> TvSubst
forall a b. (a -> b) -> a -> b
$ TCvSubst -> TCvSubst -> TCvSubst
unionTCvSubst (TvSubst -> TCvSubst
toTCv TvSubst
s1) (TvSubst -> TCvSubst
toTCv TvSubst
s2)
fromTCv :: TCvSubst -> TvSubst
fromTCv :: TCvSubst -> TvSubst
fromTCv (TCvSubst InScopeSet
set TvSubstEnv
tvsenv CvSubstEnv
_) = InScopeSet -> TvSubstEnv -> TvSubst
TvSubst InScopeSet
set TvSubstEnv
tvsenv

promotedBoolTyCon :: TyCon
promotedBoolTyCon :: TyCon
promotedBoolTyCon = TyCon
boolTyCon

viewFunTy :: Type -> Maybe (Type, Type)
viewFunTy :: Type -> Maybe (Type, Type)
viewFunTy t :: Type
t@(TyConApp TyCon
_ [Type
t1, Type
t2])
  | Type -> Bool
Old.isFunTy Type
t = (Type, Type) -> Maybe (Type, Type)
forall a. a -> Maybe a
Just (Type
t1, Type
t2)
viewFunTy Type
_ = Maybe (Type, Type)
forall a. Maybe a
Nothing

#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 802
#else
pattern FunTy :: Type -> Type -> Type
pattern FunTy t1 t2 <- (viewFunTy -> Just (t1, t2)) where
  FunTy t1 t2 = Old.mkFunTy t1 t2
#endif

tcUnifyTy :: Type -> Type -> Maybe TvSubst
tcUnifyTy :: Type -> Type -> Maybe TvSubst
tcUnifyTy Type
t1 Type
t2 = TCvSubst -> TvSubst
fromTCv (TCvSubst -> TvSubst) -> Maybe TCvSubst -> Maybe TvSubst
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Type -> Maybe TCvSubst
Old.tcUnifyTy Type
t1 Type
t2

getEqTyCon :: TcPluginM TyCon
getEqTyCon :: TcPluginM TyCon
getEqTyCon =
#if MIN_VERSION_ghc(8,8,1)
  TyCon -> TcPluginM TyCon
forall (m :: * -> *) a. Monad m => a -> m a
return TyCon
TysWiredIn.eqTyCon
#else
  tcLookupTyCon Old.eqTyConName
#endif

#else
eqType :: Type -> Type -> Bool
eqType = (==)

getEqTyCon :: TcPluginM TyCon
getEqTyCon = return Old.eqTyCon

#endif


getEqWitnessTyCon :: TcPluginM TyCon
getEqWitnessTyCon :: TcPluginM TyCon
getEqWitnessTyCon = do
  Module
md <- ModuleName -> FastString -> TcPluginM Module
lookupModule (String -> ModuleName
mkModuleName String
"Data.Type.Equality") (String -> FastString
fsLit String
"base")
  Name -> TcPluginM TyCon
tcLookupTyCon (Name -> TcPluginM TyCon) -> TcPluginM Name -> TcPluginM TyCon
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Module -> OccName -> TcPluginM Name
lookupOrig Module
md (String -> OccName
mkTcOcc String
":~:")

decompFunTy :: Type -> [Type]
#if MIN_VERSION_ghc(9,0,0)
decompFunTy (FunTy _ _ t1 t2) = t1 : decompFunTy t2
#else
#if MIN_VERSION_ghc(8,10,1)
decompFunTy :: Type -> [Type]
decompFunTy (FunTy AnonArgFlag
_ Type
t1 Type
t2) = Type
t1 Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: Type -> [Type]
decompFunTy Type
t2
#else
decompFunTy (FunTy t1 t2) = t1 : decompFunTy t2
#endif
#endif
decompFunTy Type
t             = [Type
t]

newtype TypeEq = TypeEq { TypeEq -> Type
runTypeEq :: Type }

instance Eq TypeEq where
  == :: TypeEq -> TypeEq -> Bool
(==) = Type -> Type -> Bool
forall a. Data a => a -> a -> Bool
geq (Type -> Type -> Bool)
-> (TypeEq -> Type) -> TypeEq -> TypeEq -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` TypeEq -> Type
runTypeEq

instance Ord TypeEq where
  compare :: TypeEq -> TypeEq -> Ordering
compare = Type -> Type -> Ordering
forall a. Data a => a -> a -> Ordering
gcompare (Type -> Type -> Ordering)
-> (TypeEq -> Type) -> TypeEq -> TypeEq -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` TypeEq -> Type
runTypeEq

isTrivial :: Old.PredType -> Bool
isTrivial :: Type -> Bool
isTrivial Type
ty =
  case Type -> PredTree
classifyPredType Type
ty of
    EqPred EqRel
_ Type
l Type
r -> Type
l Type -> Type -> Bool
`eqType` Type
r
    PredTree
_ -> Bool
False

normaliseGivens
  :: [Ct] -> TcPluginM [Ct]
normaliseGivens :: [Ct] -> TcPluginM [Ct]
normaliseGivens =
#if MIN_VERSION_ghc(8,4,1)
  ([Ct] -> TcPluginM [Ct])
-> ([Ct] -> [Ct]) -> [Ct] -> TcPluginM [Ct]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Ct] -> TcPluginM [Ct]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Ct] -> TcPluginM [Ct])
-> ([Ct] -> [Ct]) -> [Ct] -> TcPluginM [Ct]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ct -> Bool) -> [Ct] -> [Ct]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Ct -> Bool) -> Ct -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Bool
isTrivial (Type -> Bool) -> (Ct -> Type) -> Ct -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CtEvidence -> Type
ctEvPred (CtEvidence -> Type) -> (Ct -> CtEvidence) -> Ct -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ct -> CtEvidence
ctEvidence)) 
  (([Ct] -> [Ct]) -> [Ct] -> TcPluginM [Ct])
-> ([Ct] -> [Ct] -> [Ct]) -> [Ct] -> [Ct] -> TcPluginM [Ct]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ct] -> [Ct] -> [Ct]
forall a. [a] -> [a] -> [a]
(++) ([Ct] -> [Ct] -> TcPluginM [Ct])
-> ([Ct] -> [Ct]) -> [Ct] -> [Ct] -> TcPluginM [Ct]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Ct] -> [Ct]
forall a. a -> a
id ([Ct] -> [Ct] -> TcPluginM [Ct])
-> ([Ct] -> [Ct]) -> [Ct] -> TcPluginM [Ct]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Ct] -> [Ct]
Extra.flattenGivens
#else
  mapM zonkCt 
#endif

#if MIN_VERSION_ghc(8,4,1)
type Substitution = [(TcTyVar, TcType)]
#else
type Substitution = TvSubst
#endif

subsCt :: Substitution -> Ct -> Ct
subsCt :: Substitution -> Ct -> Ct
subsCt =
#if MIN_VERSION_ghc(8,4,1)
  Substitution -> Ct -> Ct
Extra.substCt
#else
  \subst ct ->
  ct { cc_ev = (cc_ev ct) {ctev_pred = substTy subst (ctev_pred (cc_ev ct))}
     }
#endif

subsType :: Substitution -> Type -> Type
subsType :: Substitution -> Type -> Type
subsType =
#if MIN_VERSION_ghc(8,4,1)
  Substitution -> Type -> Type
Extra.substType
#else
  substTy
#endif

mkSubstitution :: [Ct] -> Substitution
mkSubstitution :: [Ct] -> Substitution
mkSubstitution =
#if MIN_VERSION_ghc(8,4,1)
  (((TcTyVar, Type), Ct) -> (TcTyVar, Type))
-> [((TcTyVar, Type), Ct)] -> Substitution
forall a b. (a -> b) -> [a] -> [b]
map ((TcTyVar, Type), Ct) -> (TcTyVar, Type)
forall a b. (a, b) -> a
fst ([((TcTyVar, Type), Ct)] -> Substitution)
-> ([Ct] -> [((TcTyVar, Type), Ct)]) -> [Ct] -> Substitution
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ct] -> [((TcTyVar, Type), Ct)]
Extra.mkSubst'
#else
  foldr (unionTvSubst . genSubst) emptyTvSubst
#endif

#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 804
genSubst :: Ct -> TvSubst
genSubst ct = case classifyPredType (ctEvPred . ctEvidence $ ct) of
  EqPred NomEq t u -> fromMaybe emptyTvSubst $ GHC.TypeLits.Presburger.Compat.tcUnifyTy t u
  _                -> emptyTvSubst
#endif


classifyPredType :: Type -> PredTree
classifyPredType :: Type -> PredTree
classifyPredType Type
ty = case Type -> PredTree
Old.classifyPredType Type
ty of
  e :: PredTree
e@EqPred{} -> PredTree
e
  ClassPred Class
cls [Type
_,Type
t1,Type
t2]
    | Class -> Name
className Class
cls Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
eqTyConName
    -> EqRel -> Type -> Type -> PredTree
EqPred EqRel
NomEq Type
t1 Type
t2
  PredTree
e -> PredTree
e

#if MIN_VERSION_ghc(9,0,0)
fsToUnitId :: FastString -> UnitId
fsToUnitId = toUnitId . fsToUnit
#endif

type RawUnitId = FastString
preloadedUnitsM :: TcPluginM [FastString] 
#if MIN_VERSION_ghc(9,2,0)
preloadedUnitsM = do
  logger <- unsafeTcPluginTcM getLogger
  dflags <- hsc_dflags <$> getTopEnv
  packs <- tcPluginIO $ initUnits logger dflags Nothing <&> 
    \(_, us, _, _ ) -> preloadUnits us
  let packNames = map (\(UnitId p) -> p) packs
  tcPluginTrace "pres: packs" $ ppr packNames
  pure packNames
#elif MIN_VERSION_ghc(9,0,0)
preloadedUnitsM = do
  dflags <- hsc_dflags <$> getTopEnv
  packs <- tcPluginIO $ preloadUnits . unitState <$> initUnits dflags
  let packNames = map (\(UnitId p) -> p) packs
  tcPluginTrace "pres: packs" $ ppr packNames
  pure packNames
#else
preloadedUnitsM :: TcPluginM [FastString]
preloadedUnitsM = do
  DynFlags
dflags <- HscEnv -> DynFlags
hsc_dflags (HscEnv -> DynFlags) -> TcPluginM HscEnv -> TcPluginM DynFlags
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TcPluginM HscEnv
getTopEnv
  (DynFlags
_, [PreloadUnitId]
packs) <- IO (DynFlags, [PreloadUnitId])
-> TcPluginM (DynFlags, [PreloadUnitId])
forall a. IO a -> TcPluginM a
tcPluginIO (IO (DynFlags, [PreloadUnitId])
 -> TcPluginM (DynFlags, [PreloadUnitId]))
-> IO (DynFlags, [PreloadUnitId])
-> TcPluginM (DynFlags, [PreloadUnitId])
forall a b. (a -> b) -> a -> b
$ DynFlags -> IO (DynFlags, [PreloadUnitId])
initPackages DynFlags
dflags
  let packNames :: [FastString]
packNames = (PreloadUnitId -> FastString) -> [PreloadUnitId] -> [FastString]
forall a b. (a -> b) -> [a] -> [b]
map (\(InstalledUnitId FastString
p) -> FastString
p) [PreloadUnitId]
packs
  String -> SDoc -> TcPluginM ()
tcPluginTrace String
"pres: packs" (SDoc -> TcPluginM ()) -> SDoc -> TcPluginM ()
forall a b. (a -> b) -> a -> b
$ [FastString] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [FastString]
packNames
  [FastString] -> TcPluginM [FastString]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [FastString]
packNames
#endif


#if MIN_VERSION_ghc(9,0,0)
type ModuleUnit = Unit
moduleUnit' :: Module -> ModuleUnit
moduleUnit' = moduleUnit
#else
type ModuleUnit = UnitId
moduleUnit' :: Module -> ModuleUnit
moduleUnit' :: Module -> ModuleUnit
moduleUnit' = Module -> ModuleUnit
GHC.moduleUnitId
#endif

#if !MIN_VERSION_ghc(8,10,1)
type NoExtField = NoExt
#endif

noExtField :: NoExtField
#if MIN_VERSION_ghc(8,10,1)
noExtField :: NoExtField
noExtField = NoExtField
NoExtField
#else
noExtField = NoExt
#endif

#if MIN_VERSION_ghc(9,0,1)
type HsModule' = HsModule
#else
type HsModule' = GHC.HsModule GHC.GhcPs
#endif

#if !MIN_VERSION_ghc(9,0,1)
type IsBootInterface = Bool
pattern NotBoot :: IsBootInterface
pattern $bNotBoot :: Bool
$mNotBoot :: forall r. Bool -> (Void# -> r) -> (Void# -> r) -> r
NotBoot = False

pattern IsBoot :: IsBootInterface
pattern $bIsBoot :: Bool
$mIsBoot :: forall r. Bool -> (Void# -> r) -> (Void# -> r) -> r
IsBoot = True

{-# COMPLETE NotBoot, IsBoot #-}

#endif
#if MIN_VERSION_ghc(9,2,0)
typeNatKind :: TcType
typeNatKind = naturalTy
#endif

mtypeNatLeqTyCon :: Maybe TyCon
#if MIN_VERSION_ghc(9,2,0)
mtypeNatLeqTyCon = Nothing
#else
mtypeNatLeqTyCon :: Maybe TyCon
mtypeNatLeqTyCon = TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just TyCon
typeNatLeqTyCon
#endif

lookupTyNatPredLeq :: TcPluginM Name
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatPredLeq = do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  lookupOrig tyOrd (mkTcOcc "<=")
#else
lookupTyNatPredLeq :: TcPluginM Name
lookupTyNatPredLeq = 
  Module -> OccName -> TcPluginM Name
lookupOrig Module
gHC_TYPENATS (String -> OccName
mkTcOcc String
"<=")
#endif

lookupTyNatBoolLeq :: TcPluginM TyCon
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatBoolLeq = do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc "<=?")
#else
lookupTyNatBoolLeq :: TcPluginM TyCon
lookupTyNatBoolLeq = 
  TyCon -> TcPluginM TyCon
forall (f :: * -> *) a. Applicative f => a -> f a
pure TyCon
typeNatLeqTyCon
#endif

lookupTyNatPredLt :: TcPluginM (Maybe TyCon)
-- Note:  base library shipepd with 9.2.1 has a wrong implementation;
-- hence we MUST NOT desugar it with <= 9.2.1
#if MIN_VERSION_ghc(9,2,2)
lookupTyNatPredLt = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc "<")
#else
lookupTyNatPredLt :: TcPluginM (Maybe TyCon)
lookupTyNatPredLt = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

lookupTyNatBoolLt :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatBoolLt = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc "<?")
#else
lookupTyNatBoolLt :: TcPluginM (Maybe TyCon)
lookupTyNatBoolLt = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

lookupTyNatPredGt :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatPredGt = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc ">")
#else
lookupTyNatPredGt :: TcPluginM (Maybe TyCon)
lookupTyNatPredGt = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

lookupTyNatBoolGt :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatBoolGt = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc ">?")
#else
lookupTyNatBoolGt :: TcPluginM (Maybe TyCon)
lookupTyNatBoolGt = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

lookupTyNatPredGeq :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatPredGeq = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc ">=")
#else
lookupTyNatPredGeq :: TcPluginM (Maybe TyCon)
lookupTyNatPredGeq = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

lookupTyNatBoolGeq :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
lookupTyNatBoolGeq = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc ">=?")
#else
lookupTyNatBoolGeq :: TcPluginM (Maybe TyCon)
lookupTyNatBoolGeq = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

mOrdCondTyCon :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
mOrdCondTyCon = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc "OrdCond")
#else
mOrdCondTyCon :: TcPluginM (Maybe TyCon)
mOrdCondTyCon = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif

lookupTyGenericCompare :: TcPluginM (Maybe TyCon)
#if MIN_VERSION_ghc(9,2,0)
lookupTyGenericCompare = Just <$> do
  tyOrd <- lookupModule (mkModuleName "Data.Type.Ord") "base"
  tcLookupTyCon =<< lookupOrig tyOrd (mkTcOcc "Compare")
#else
lookupTyGenericCompare :: TcPluginM (Maybe TyCon)
lookupTyGenericCompare = Maybe TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
#endif