+
+%************************************************************************
+%* *
+\subsection[Generic]{Generic flag}
+%* *
+%************************************************************************
+
+This is the "Embedding-Projection pair" datatype, it contains
+two pieces of code (normally either RenamedExpr's or Id's)
+If we have a such a pair (EP from to), the idea is that 'from' and 'to'
+represents functions of type
+
+ from :: T -> Tring
+ to :: Tring -> T
+
+And we should have
+
+ to (from x) = x
+
+T and Tring are arbitrary, but typically T is the 'main' type while
+Tring is the 'representation' type. (This just helps us remember
+whether to use 'from' or 'to'.
+
+\begin{code}
+data EP a = EP { fromEP :: a, -- :: T -> Tring
+ toEP :: a } -- :: Tring -> T
+\end{code}
+
+Embedding-projection pairs are used in several places:
+
+First of all, each type constructor has an EP associated with it, the
+code in EP converts (datatype T) from T to Tring and back again.
+
+Secondly, when we are filling in Generic methods (in the typechecker,
+tcMethodBinds), we are constructing bimaps by induction on the structure
+of the type of the method signature.
+
+
+%************************************************************************
+%* *
+\subsection{Occurrence information}
+%* *
+%************************************************************************
+
+This data type is used exclusively by the simplifier, but it appears in a
+SubstResult, which is currently defined in VarEnv, which is pretty near
+the base of the module hierarchy. So it seemed simpler to put the
+defn of OccInfo here, safely at the bottom
+
+\begin{code}
+data OccInfo
+ = NoOccInfo
+
+ | IAmDead -- Marks unused variables. Sometimes useful for
+ -- lambda and case-bound variables.
+
+ | OneOcc InsideLam
+
+ OneBranch
+
+ | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
+ -- in a group of recursive definitions
+
+seqOccInfo :: OccInfo -> ()
+seqOccInfo (OneOcc in_lam once) = in_lam `seq` once `seq` ()
+seqOccInfo occ = ()
+
+type InsideLam = Bool -- True <=> Occurs inside a non-linear lambda
+ -- Substituting a redex for this occurrence is
+ -- dangerous because it might duplicate work.
+insideLam = True
+notInsideLam = False
+
+type OneBranch = Bool -- True <=> Occurs in only one case branch
+ -- so no code-duplication issue to worry about
+oneBranch = True
+notOneBranch = False
+
+isLoopBreaker :: OccInfo -> Bool
+isLoopBreaker IAmALoopBreaker = True
+isLoopBreaker other = False
+
+isDeadOcc :: OccInfo -> Bool
+isDeadOcc IAmDead = True
+isDeadOcc other = False
+
+isOneOcc (OneOcc _ _) = True
+isOneOcc other = False
+
+isFragileOcc :: OccInfo -> Bool
+isFragileOcc (OneOcc _ _) = True
+isFragileOcc other = False
+\end{code}
+
+\begin{code}
+instance Outputable OccInfo where
+ -- only used for debugging; never parsed. KSW 1999-07
+ ppr NoOccInfo = empty
+ ppr IAmALoopBreaker = ptext SLIT("_Kx")
+ ppr IAmDead = ptext SLIT("_Kd")
+ ppr (OneOcc inside_lam one_branch) | inside_lam = ptext SLIT("_Kl")
+ | one_branch = ptext SLIT("_Ks")
+ | otherwise = ptext SLIT("_Ks*")
+
+instance Show OccInfo where
+ showsPrec p occ = showsPrecSDoc p (ppr occ)
+\end{code}
+
+%************************************************************************
+%* *
+\subsection{Strictness indication}
+%* *
+%************************************************************************
+
+The strictness annotations on types in data type declarations
+e.g. data T = MkT !Int !(Bool,Bool)
+
+\begin{code}
+data StrictnessMark -- Used in interface decls only
+ = MarkedStrict
+ | MarkedUnboxed
+ | NotMarkedStrict
+ deriving( Eq )
+
+isMarkedUnboxed MarkedUnboxed = True
+isMarkedUnboxed other = False
+
+isMarkedStrict NotMarkedStrict = False
+isMarkedStrict other = True -- All others are strict
+
+instance Outputable StrictnessMark where
+ ppr MarkedStrict = ptext SLIT("!")
+ ppr MarkedUnboxed = ptext SLIT("!!")
+ ppr NotMarkedStrict = ptext SLIT("_")
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Success flag}
+%* *
+%************************************************************************
+
+\begin{code}
+data SuccessFlag = Succeeded | Failed
+
+successIf :: Bool -> SuccessFlag
+successIf True = Succeeded
+successIf False = Failed
+
+succeeded, failed :: SuccessFlag -> Bool
+succeeded Succeeded = True
+succeeded Failed = False
+
+failed Succeeded = False
+failed Failed = True
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Activation}
+%* *
+%************************************************************************
+
+When a rule or inlining is active
+
+\begin{code}
+type CompilerPhase = Int -- Compilation phase
+ -- Phases decrease towards zero
+ -- Zero is the last phase
+
+data Activation = NeverActive
+ | AlwaysActive
+ | ActiveBefore CompilerPhase -- Active only *before* this phase
+ | ActiveAfter CompilerPhase -- Active in this phase and later
+ deriving( Eq ) -- Eq used in comparing rules in HsDecls
+
+instance Outputable Activation where
+ ppr AlwaysActive = empty -- The default
+ ppr (ActiveBefore n) = brackets (char '~' <> int n)
+ ppr (ActiveAfter n) = brackets (int n)
+ ppr NeverActive = ptext SLIT("NEVER")
+
+isActive :: CompilerPhase -> Activation -> Bool
+isActive p NeverActive = False
+isActive p AlwaysActive = True
+isActive p (ActiveAfter n) = p <= n
+isActive p (ActiveBefore n) = p > n
+
+isNeverActive, isAlwaysActive :: Activation -> Bool
+isNeverActive NeverActive = True
+isNeverActive act = False
+
+isAlwaysActive AlwaysActive = True
+isAlwaysActive other = False
+\end{code}
+