module GHC.Tc.Types.CtLocEnv (
    CtLocEnv(..)
  , getCtLocEnvLoc
  , getCtLocEnvLvl
  , setCtLocEnvLvl
  , setCtLocRealLoc
  , setCtLocEnvLoc
  , ctLocEnvInGeneratedCode
  ) where

import GHC.Prelude

import GHC.Types.SrcLoc
import GHC.Types.Name.Reader

import GHC.Tc.Types.BasicTypes
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.ErrCtxt


-- | Local typechecker environment for a constraint.
--
-- Used to restore the environment of a constraint
-- when reporting errors, see `setCtLocM`.
--
-- See also 'TcLclCtxt'.
data CtLocEnv = CtLocEnv { CtLocEnv -> [ErrCtxt]
ctl_ctxt :: ![ErrCtxt]
                         , CtLocEnv -> RealSrcSpan
ctl_loc :: !RealSrcSpan
                         , CtLocEnv -> TcBinderStack
ctl_bndrs :: !TcBinderStack
                         , CtLocEnv -> TcLevel
ctl_tclvl :: !TcLevel
                         , CtLocEnv -> Bool
ctl_in_gen_code :: !Bool
                         , CtLocEnv -> LocalRdrEnv
ctl_rdr :: !LocalRdrEnv }


getCtLocEnvLoc :: CtLocEnv -> RealSrcSpan
getCtLocEnvLoc :: CtLocEnv -> RealSrcSpan
getCtLocEnvLoc = CtLocEnv -> RealSrcSpan
ctl_loc

getCtLocEnvLvl :: CtLocEnv -> TcLevel
getCtLocEnvLvl :: CtLocEnv -> TcLevel
getCtLocEnvLvl = CtLocEnv -> TcLevel
ctl_tclvl

setCtLocEnvLvl :: CtLocEnv -> TcLevel -> CtLocEnv
setCtLocEnvLvl :: CtLocEnv -> TcLevel -> CtLocEnv
setCtLocEnvLvl CtLocEnv
env TcLevel
lvl = CtLocEnv
env { ctl_tclvl = lvl }

setCtLocRealLoc :: CtLocEnv -> RealSrcSpan -> CtLocEnv
setCtLocRealLoc :: CtLocEnv -> RealSrcSpan -> CtLocEnv
setCtLocRealLoc CtLocEnv
env RealSrcSpan
ss = CtLocEnv
env { ctl_loc = ss }

setCtLocEnvLoc :: CtLocEnv -> SrcSpan -> CtLocEnv
-- See Note [Error contexts in generated code]
-- for the ctl_in_gen_code manipulation
setCtLocEnvLoc :: CtLocEnv -> SrcSpan -> CtLocEnv
setCtLocEnvLoc CtLocEnv
env (RealSrcSpan RealSrcSpan
loc Maybe BufSpan
_)
  = CtLocEnv
env { ctl_loc = loc, ctl_in_gen_code = False }

setCtLocEnvLoc CtLocEnv
env loc :: SrcSpan
loc@(UnhelpfulSpan UnhelpfulSpanReason
_)
  | SrcSpan -> Bool
isGeneratedSrcSpan SrcSpan
loc
  = CtLocEnv
env { ctl_in_gen_code = True }
  | Bool
otherwise
  = CtLocEnv
env

ctLocEnvInGeneratedCode :: CtLocEnv -> Bool
ctLocEnvInGeneratedCode :: CtLocEnv -> Bool
ctLocEnvInGeneratedCode = CtLocEnv -> Bool
ctl_in_gen_code