content: {-# LANGUAGE ConstraintKinds #-}
  {-# LANGUAGE CPP #-}
  {-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE FunctionalDependencies #-}
  {-# LANGUAGE ImplicitParams #-}
  {-# LANGUAGE TypeFamilies #-}
  {-# LANGUAGE TypeOperators #-}
  {- HLINT ignore "Use camelCase" -}
  {- HLINT ignore "Unused LANGUAGE pragma" -}
  
  -- | Module containing the plugin.
  module Compat(module Compat) where
  
  import GHC
  #if __GLASGOW_HASKELL__ > 901
  import GHC.Types.SourceText ( SourceText(NoSourceText) )
  import GHC.Data.FastString (FastString, NonDetFastString (NonDetFastString))
  #elif __GLASGOW_HASKELL__ >=900
  import GHC.Data.FastString (FastString)
  #else
  import FastString (FastString)
  #endif
  
  #if __GLASGOW_HASKELL__ < 900
  import BasicTypes
  import TcEvidence
  import RnTypes as Compat
  import UniqSupply
  #else
  import GHC.Types.Basic
  #if __GLASGOW_HASKELL__ < 906
  import GHC.Unit.Types
  #endif
  #if __GLASGOW_HASKELL__ < 902
  import GHC.Parser.Annotation
  #endif
  import GHC.Rename.HsType as Compat
  import GHC.Types.Unique.Supply
  #endif
  #if __GLASGOW_HASKELL__ < 810
  import HsSyn as Compat
  #else
  import GHC.Hs as Compat
  #endif
  #if __GLASGOW_HASKELL__ < 808
  import System.IO.Unsafe as Compat (unsafePerformIO)
  import TcRnTypes
  import IOEnv
  import DynFlags
  import HscTypes
  #endif
  #if __GLASGOW_HASKELL__ >= 904
  import GHC.Types.PkgQual (RawPkgQual(NoRawPkgQual))
  #endif
  import Data.IORef as Compat
  
  ---------------------------------------------------------------------
  -- LOCATIONS
  
  class WithoutLoc a b | b -> a where
    -- | Without location information
    --
    -- Different GHC versions want different kind of location information in
    -- different places. This class is intended to abstract over this.
    noL :: a -> b
  
  #if __GLASGOW_HASKELL__ >= 902
  instance WithoutLoc a (GenLocated (SrcAnn ann) a) where
    noL = reLocA . noLoc
  #endif
  
  instance WithoutLoc a (Located a) where
    noL = noLoc
  
  instance WithoutLoc (HsTupArg p)         (HsTupArg p)         where noL = id
  instance WithoutLoc (HsLocalBindsLR p q) (HsLocalBindsLR p q) where noL = id
  
  #if __GLASGOW_HASKELL__ < 902
  reLocA :: Located e -> Located e
  reLocA = id
  
  reLoc :: Located e -> Located e
  reLoc = id
  #endif
  
  ---------------------------------------------------------------------
  -- TREE EXTENSIONS
  
  class WithoutExt a where
    -- | No extension
    --
    -- Different GHC versions want different kinds of annotations. This class is
    -- intended to abstract over this.
    noE :: a
  
  #if __GLASGOW_HASKELL__ >= 902
  instance WithoutExt (EpAnn a) where
    noE = EpAnnNotUsed
  
  instance WithoutExt EpAnnComments where
    noE = emptyComments
  #endif
  
  #if __GLASGOW_HASKELL__ >= 810
  instance WithoutExt NoExtField where
    noE = noExtField
  #else
  instance WithoutExt NoExt where
    noE = NoExt
  #endif
  
  #if __GLASGOW_HASKELL__ >= 906
  instance WithoutExt XImportDeclPass where
    noE = XImportDeclPass noE NoSourceText True {- implicit -}
  
  instance WithoutExt GHC.Types.Basic.Origin where
    noE = Generated
  #if __GLASGOW_HASKELL__ >= 908
            SkipPmc
  #endif
  #endif
  
  ---------------------------------------------------------------------
  -- UTILITIES
  
  #if __GLASGOW_HASKELL__ < 902
  
  mkNonDetFastString :: FastString -> FastString
  mkNonDetFastString = id
  
  #else
  
  mkNonDetFastString :: FastString -> NonDetFastString
  mkNonDetFastString = NonDetFastString
  
  #endif
  
  realSrcLoc :: SrcLoc -> Maybe RealSrcLoc
  #if __GLASGOW_HASKELL__ < 811
  realSrcLoc (RealSrcLoc x) = Just x
  #else
  realSrcLoc (RealSrcLoc x _) = Just x
  #endif
  realSrcLoc _ = Nothing
  
  #if __GLASGOW_HASKELL__ >= 902
  hsLTyVarBndrToType :: (Anno (IdP (GhcPass p)) ~ SrcSpanAnn' (EpAnn NameAnn)) => LHsTyVarBndr flag (GhcPass p) -> LHsType (GhcPass p)
  hsLTyVarBndrToType x = noL $ HsTyVar noE NotPromoted $ noL $ hsLTyVarName x
  #elif __GLASGOW_HASKELL__ >= 900
  hsLTyVarBndrToType :: LHsTyVarBndr flag (GhcPass p) -> LHsType (GhcPass p)
  hsLTyVarBndrToType x = noL $ HsTyVar noE NotPromoted $ noL $ hsLTyVarName x
  #endif
  
  ---------------------------------------------------------------------
  -- COMMON SIGNATURES
  
  #if __GLASGOW_HASKELL__ < 811
  type Module = HsModule GhcPs
  #elif __GLASGOW_HASKELL__ >= 906
  type Module = HsModule GhcPs
  #else
  type Module = HsModule
  #endif
  
  mkAppType :: LHsExpr GhcPs -> LHsType GhcPs -> LHsExpr GhcPs
  mkTypeAnn :: LHsExpr GhcPs -> LHsType GhcPs -> LHsExpr GhcPs
  mkFunTy :: LHsType GhcPs -> LHsType GhcPs -> LHsType GhcPs
  newFunBind :: Located RdrName -> MatchGroup GhcPs (LHsExpr GhcPs) -> HsBind GhcPs
  
  #if __GLASGOW_HASKELL__ < 807
  
  -- GHC 8.6
  mkAppType expr typ = noL $ HsAppType (HsWC noE typ) expr
  mkTypeAnn expr typ = noL $ ExprWithTySig (HsWC noE (HsIB noE typ)) expr
  
  #elif __GLASGOW_HASKELL__ < 901
  
  -- GHC 8.8-9.0
  mkAppType expr typ = noL $ HsAppType noE expr (HsWC noE typ)
  mkTypeAnn expr typ = noL $ ExprWithTySig noE expr (HsWC noE (HsIB noE typ))
  
  #elif __GLASGOW_HASKELL__ >= 906
  
  -- GHC 9.6+
  mkAppType expr typ = noL $ HsAppType noE expr noHsTok (HsWC noE typ)
  mkTypeAnn expr typ = noL $ ExprWithTySig noE expr (hsTypeToHsSigWcType typ)
  
  #else
  
  -- GHC 9.2-9.4
  mkAppType expr typ = noL $ HsAppType noSrcSpan expr (HsWC noE typ)
  mkTypeAnn expr typ = noL $ ExprWithTySig noE expr (hsTypeToHsSigWcType typ)
  
  #endif
  
  #if __GLASGOW_HASKELL__ < 811
  
  -- GHC 8.10 and below
  mkFunTy a b = noL $ HsFunTy noE a b
  newFunBind a b = FunBind noE a b WpHole []
  
  #elif __GLASGOW_HASKELL__ < 904
  
  -- GHC 9.0 and 9.2
  mkFunTy a b = noL $ HsFunTy noE (HsUnrestrictedArrow NormalSyntax) a b
  newFunBind a b = FunBind noE (reLocA a) b []
  
  #elif __GLASGOW_HASKELL__ >= 906
  
  -- GHC 9.6+
  mkFunTy a b = noL $ HsFunTy noE (HsUnrestrictedArrow $ L NoTokenLoc HsNormalTok) a b
  newFunBind a = FunBind noE (reLocA a)
  
  #else
  
  -- GHC 9.4
  mkFunTy a b = noL $ HsFunTy noE (HsUnrestrictedArrow $ L NoTokenLoc HsNormalTok) a b
  newFunBind a b = FunBind noE (reLocA a) b []
  
  #endif
  
  
  #if __GLASGOW_HASKELL__ < 807
  
  -- GHC 8.6
  compat_m_pats :: [Pat GhcPs] -> [LPat GhcPs]
  compat_m_pats = map noL
  
  #elif __GLASGOW_HASKELL__ < 809
  
  -- GHC 8.8
  compat_m_pats :: [Pat GhcPs] -> [Pat GhcPs]
  compat_m_pats = id
  
  #else
  
  -- 8.10
  compat_m_pats :: [Pat GhcPs] -> [LPat GhcPs]
  compat_m_pats = map noL
  
  #endif
  
  
  qualifiedImplicitImport :: ModuleName -> LImportDecl GhcPs
  
  #if __GLASGOW_HASKELL__ < 809
  
  -- GHC 8.8
  qualifiedImplicitImport x = noL $ ImportDecl noE NoSourceText (noL x) Nothing False False
      True {- qualified -} True {- implicit -} Nothing Nothing
  
  #elif __GLASGOW_HASKELL__ < 811
  
  -- GHC 8.10
  qualifiedImplicitImport x = noL $ ImportDecl noE NoSourceText (noL x) Nothing False False
      QualifiedPost {- qualified -} True {- implicit -} Nothing Nothing
  
  #elif __GLASGOW_HASKELL__ < 904
  
  -- GHC 9.0 and 9.2
  qualifiedImplicitImport x = noL $ ImportDecl noE NoSourceText (noL x) Nothing NotBoot False
      QualifiedPost {- qualified -} True {- implicit -} Nothing Nothing
  
  #elif __GLASGOW_HASKELL__ >= 906
  
  -- GHC 9.6+
  qualifiedImplicitImport x = noL $ ImportDecl noE (noL x) NoRawPkgQual NotBoot False
      QualifiedPost {- qualified -} Nothing Nothing
  
  #else
  
  -- GHC 9.4
  qualifiedImplicitImport x = noL $ ImportDecl noE NoSourceText (noL x) NoRawPkgQual NotBoot False
      QualifiedPost {- qualified -} True {- implicit -} Nothing Nothing
  
  #endif
  
  type PluginEnv = (?hscenv :: HscEnv, ?uniqSupply :: IORef UniqSupply)
  
  dropRnTraceFlags :: HscEnv -> HscEnv
  #if __GLASGOW_HASKELL__ < 808
  dropRnTraceFlags env@HscEnv{hsc_dflags = dflags} =  env{hsc_dflags = dopt_unset dflags Opt_D_dump_rn_trace}
  #else
  dropRnTraceFlags = id
  #endif
  
  freeTyVars :: PluginEnv => LHsType GhcPs -> [Located RdrName]
  #if __GLASGOW_HASKELL__ < 808
  {-# NOINLINE freeTyVars #-}
  freeTyVars  = freeKiTyVarsAllVars . runRnM . extractHsTyRdrTyVars
    where
      runRnM :: RnM a -> a
      runRnM rnm = unsafePerformIO $ do
        let env = Env ?hscenv ?uniqSupply unused unused
        runIOEnv env rnm
      unused = error "never called"
  #elif __GLASGOW_HASKELL__ < 810
  freeTyVars = freeKiTyVarsAllVars . extractHsTyRdrTyVars
  #else
  freeTyVars = map reLoc . extractHsTyRdrTyVars
  #endif
  
  #if __GLASGOW_HASKELL__ >= 902
  isLHsForAllTy :: LHsType GhcPs -> Bool
  isLHsForAllTy (L _ (HsForAllTy {})) = True
  isLHsForAllTy _                     = False
  #endif
  
  #if __GLASGOW_HASKELL__ >= 904
  rdrNameFieldOcc :: FieldOcc GhcPs -> LocatedN RdrName
  rdrNameFieldOcc = foLabel
  #endif
  