{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE UndecidableInstances #-} -- NFData InlinePragma

module Language.Haskell.Syntax.Binds.InlinePragma
  ( -- * Inline Pragma Encoding
    -- ** InlinePragma
    -- *** Data-type
    InlinePragma(..)
    -- *** Queries
  , isAnyInlinePragma
  , isInlinablePragma
  , isInlinePragma
  , isNoInlinePragma
  , isOpaquePragma

    -- ** InlineSpec
    -- *** Data-type
  , InlineSpec(..)
    -- *** Queries
  , noUserInlineSpec

    -- ** RuleMatchInfo
    -- *** Data-type
  , RuleMatchInfo(..)
    -- *** Queries
  , isConLike
  , isFunLike

    -- * Phase Activation
    -- ** Activation
    -- *** Data-type
  , Activation
  , ActivationX(..)
  , PhaseNum
  ) where

import Language.Haskell.Syntax.Extension

import Control.DeepSeq (NFData(..))
import Data.Bool
import Data.Data (Data)

import Prelude -- (Eq, Int, Show, ($), seq)

{-
************************************************************************
*                                                                      *
\subsection[InlinePragma]{The InlinePragma definitions}
*                                                                      *
************************************************************************
-}

data InlinePragma pass                      -- Note [InlinePragma]
  = InlinePragma
      { forall pass. InlinePragma pass -> XInlinePragma pass
inl_ext    :: !(XInlinePragma pass) -- See Note [Pragma source text]
      , forall pass. InlinePragma pass -> InlineSpec
inl_inline :: !InlineSpec           -- See Note [inl_inline and inl_act]
      , forall pass. InlinePragma pass -> Activation pass
inl_act    :: !(Activation pass)    -- Says during which phases inlining is allowed
                                            -- See Note [inl_inline and inl_act]
      , forall pass. InlinePragma pass -> RuleMatchInfo
inl_rule   :: !RuleMatchInfo        -- Should the function be treated like a constructor?
    }
  | XInlinePragma !(XXInlinePragma pass)

deriving instance ( Eq (XXActivation pass)
                  , Eq (XInlinePragma pass)
                  , Eq (XXInlinePragma pass)) => Eq (InlinePragma pass)

instance ( NFData (XInlinePragma p)
         , NFData (XXInlinePragma p)
         , NFData (XXActivation p)) => NFData (InlinePragma p) where
  rnf :: InlinePragma p -> ()
rnf (InlinePragma XInlinePragma p
x InlineSpec
a ActivationX (XXActivation p)
b RuleMatchInfo
c) = XInlinePragma p -> ()
forall a. NFData a => a -> ()
rnf XInlinePragma p
x () -> () -> ()
forall a b. a -> b -> b
`seq` InlineSpec -> ()
forall a. NFData a => a -> ()
rnf InlineSpec
a () -> () -> ()
forall a b. a -> b -> b
`seq` ActivationX (XXActivation p) -> ()
forall a. NFData a => a -> ()
rnf ActivationX (XXActivation p)
b () -> () -> ()
forall a b. a -> b -> b
`seq` RuleMatchInfo -> ()
forall a. NFData a => a -> ()
rnf RuleMatchInfo
c
  rnf (XInlinePragma XXInlinePragma p
x) = XXInlinePragma p -> ()
forall a. NFData a => a -> ()
rnf XXInlinePragma p
x

-- | Inline Specification
data InlineSpec -- What the user's INLINE pragma looked like
  = Inline      -- User wrote INLINE
  | Inlinable   -- User wrote INLINABLE
  | NoInline    -- User wrote NOINLINE
  | Opaque      -- User wrote OPAQUE
                -- Each of the above keywords is accompanied with
                -- a string of type SourceText written by the user
  | NoUserInlinePrag -- User did not write any of INLINE/INLINABLE/NOINLINE
                     -- e.g. in `defaultInlinePragma` or when created by CSE
  deriving( InlineSpec -> InlineSpec -> Bool
(InlineSpec -> InlineSpec -> Bool)
-> (InlineSpec -> InlineSpec -> Bool) -> Eq InlineSpec
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InlineSpec -> InlineSpec -> Bool
== :: InlineSpec -> InlineSpec -> Bool
$c/= :: InlineSpec -> InlineSpec -> Bool
/= :: InlineSpec -> InlineSpec -> Bool
Eq, Typeable InlineSpec
Typeable InlineSpec =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> InlineSpec -> c InlineSpec)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c InlineSpec)
-> (InlineSpec -> Constr)
-> (InlineSpec -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c InlineSpec))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c InlineSpec))
-> ((forall b. Data b => b -> b) -> InlineSpec -> InlineSpec)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> InlineSpec -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> InlineSpec -> r)
-> (forall u. (forall d. Data d => d -> u) -> InlineSpec -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> InlineSpec -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec)
-> Data InlineSpec
InlineSpec -> Constr
InlineSpec -> DataType
(forall b. Data b => b -> b) -> InlineSpec -> InlineSpec
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> InlineSpec -> u
forall u. (forall d. Data d => d -> u) -> InlineSpec -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InlineSpec -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InlineSpec -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c InlineSpec
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> InlineSpec -> c InlineSpec
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c InlineSpec)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c InlineSpec)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> InlineSpec -> c InlineSpec
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> InlineSpec -> c InlineSpec
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c InlineSpec
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c InlineSpec
$ctoConstr :: InlineSpec -> Constr
toConstr :: InlineSpec -> Constr
$cdataTypeOf :: InlineSpec -> DataType
dataTypeOf :: InlineSpec -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c InlineSpec)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c InlineSpec)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c InlineSpec)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c InlineSpec)
$cgmapT :: (forall b. Data b => b -> b) -> InlineSpec -> InlineSpec
gmapT :: (forall b. Data b => b -> b) -> InlineSpec -> InlineSpec
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InlineSpec -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> InlineSpec -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InlineSpec -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> InlineSpec -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> InlineSpec -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> InlineSpec -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> InlineSpec -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> InlineSpec -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> InlineSpec -> m InlineSpec
Data, Int -> InlineSpec -> ShowS
[InlineSpec] -> ShowS
InlineSpec -> String
(Int -> InlineSpec -> ShowS)
-> (InlineSpec -> String)
-> ([InlineSpec] -> ShowS)
-> Show InlineSpec
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InlineSpec -> ShowS
showsPrec :: Int -> InlineSpec -> ShowS
$cshow :: InlineSpec -> String
show :: InlineSpec -> String
$cshowList :: [InlineSpec] -> ShowS
showList :: [InlineSpec] -> ShowS
Show )
        -- Show needed for GHC.Parser.Lexer

instance NFData InlineSpec where
  rnf :: InlineSpec -> ()
rnf = \case
    InlineSpec
Inline -> ()
    InlineSpec
Inlinable -> ()
    InlineSpec
NoInline -> ()
    InlineSpec
Opaque -> ()
    InlineSpec
NoUserInlinePrag -> ()

-- | Rule Match Information
data RuleMatchInfo
  = ConLike -- See Note [CONLIKE pragma]
  | FunLike
  deriving( RuleMatchInfo -> RuleMatchInfo -> Bool
(RuleMatchInfo -> RuleMatchInfo -> Bool)
-> (RuleMatchInfo -> RuleMatchInfo -> Bool) -> Eq RuleMatchInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RuleMatchInfo -> RuleMatchInfo -> Bool
== :: RuleMatchInfo -> RuleMatchInfo -> Bool
$c/= :: RuleMatchInfo -> RuleMatchInfo -> Bool
/= :: RuleMatchInfo -> RuleMatchInfo -> Bool
Eq, Typeable RuleMatchInfo
Typeable RuleMatchInfo =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> RuleMatchInfo -> c RuleMatchInfo)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c RuleMatchInfo)
-> (RuleMatchInfo -> Constr)
-> (RuleMatchInfo -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c RuleMatchInfo))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c RuleMatchInfo))
-> ((forall b. Data b => b -> b) -> RuleMatchInfo -> RuleMatchInfo)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r)
-> (forall u. (forall d. Data d => d -> u) -> RuleMatchInfo -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> RuleMatchInfo -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo)
-> Data RuleMatchInfo
RuleMatchInfo -> Constr
RuleMatchInfo -> DataType
(forall b. Data b => b -> b) -> RuleMatchInfo -> RuleMatchInfo
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> RuleMatchInfo -> u
forall u. (forall d. Data d => d -> u) -> RuleMatchInfo -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c RuleMatchInfo
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> RuleMatchInfo -> c RuleMatchInfo
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c RuleMatchInfo)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c RuleMatchInfo)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> RuleMatchInfo -> c RuleMatchInfo
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> RuleMatchInfo -> c RuleMatchInfo
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c RuleMatchInfo
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c RuleMatchInfo
$ctoConstr :: RuleMatchInfo -> Constr
toConstr :: RuleMatchInfo -> Constr
$cdataTypeOf :: RuleMatchInfo -> DataType
dataTypeOf :: RuleMatchInfo -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c RuleMatchInfo)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c RuleMatchInfo)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c RuleMatchInfo)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c RuleMatchInfo)
$cgmapT :: (forall b. Data b => b -> b) -> RuleMatchInfo -> RuleMatchInfo
gmapT :: (forall b. Data b => b -> b) -> RuleMatchInfo -> RuleMatchInfo
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> RuleMatchInfo -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> RuleMatchInfo -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> RuleMatchInfo -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> RuleMatchInfo -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> RuleMatchInfo -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> RuleMatchInfo -> m RuleMatchInfo
Data, Int -> RuleMatchInfo -> ShowS
[RuleMatchInfo] -> ShowS
RuleMatchInfo -> String
(Int -> RuleMatchInfo -> ShowS)
-> (RuleMatchInfo -> String)
-> ([RuleMatchInfo] -> ShowS)
-> Show RuleMatchInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RuleMatchInfo -> ShowS
showsPrec :: Int -> RuleMatchInfo -> ShowS
$cshow :: RuleMatchInfo -> String
show :: RuleMatchInfo -> String
$cshowList :: [RuleMatchInfo] -> ShowS
showList :: [RuleMatchInfo] -> ShowS
Show )
        -- Show needed for GHC.Parser.Lexer

instance NFData RuleMatchInfo where
  rnf :: RuleMatchInfo -> ()
rnf = \case
    RuleMatchInfo
ConLike -> ()
    RuleMatchInfo
FunLike -> ()

{- Note [InlinePragma]
~~~~~~~~~~~~~~~~~~~~~~
This data type mirrors what you can write in an INLINE or NOINLINE pragma in
the source program.

If you write nothing at all, you get defaultInlinePragma:
   inl_inline = NoUserInlinePrag
   inl_act    = AlwaysActive
   inl_rule   = FunLike

It's not possible to get that combination by *writing* something, so
if an Id has defaultInlinePragma it means the user didn't specify anything.

If inl_inline = Inline or Inlineable, then the Id should have a stable unfolding.

If you want to know where InlinePragmas take effect: Look in GHC.HsToCore.Binds.makeCorePair

Note [inl_inline and inl_act]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* inl_inline says what the user wrote: did they say INLINE, NOINLINE,
  INLINABLE, OPAQUE, or nothing at all

* inl_act says in what phases the unfolding is active or inactive
  E.g  If you write INLINE[1]    then inl_act will be set to ActiveAfter 1
       If you write NOINLINE[1]  then inl_act will be set to ActiveBefore 1
       If you write NOINLINE[~1] then inl_act will be set to ActiveAfter 1
  So note that inl_act does not say what pragma you wrote: it just
  expresses its consequences

* inl_act just says when the unfolding is active; it doesn't say what
  to inline.  If you say INLINE f, then f's inl_act will be AlwaysActive,
  but in addition f will get a "stable unfolding" with UnfoldingGuidance
  that tells the inliner to be pretty eager about it.

Note [CONLIKE pragma]
~~~~~~~~~~~~~~~~~~~~~
The ConLike constructor of a RuleMatchInfo is aimed at the following.
Consider first
    {-# RULE "r/cons" forall a as. r (a:as) = f (a+1) #-}
    g b bs = let x = b:bs in ..x...x...(r x)...
Now, the rule applies to the (r x) term, because GHC "looks through"
the definition of 'x' to see that it is (b:bs).

Now consider
    {-# RULE "r/f" forall v. r (f v) = f (v+1) #-}
    g v = let x = f v in ..x...x...(r x)...
Normally the (r x) would *not* match the rule, because GHC would be
scared about duplicating the redex (f v), so it does not "look
through" the bindings.

However the CONLIKE modifier says to treat 'f' like a constructor in
this situation, and "look through" the unfolding for x.  So (r x)
fires, yielding (f (v+1)).

This is all controlled with a user-visible pragma:
     {-# NOINLINE CONLIKE [1] f #-}

The main effects of CONLIKE are:

    - The occurrence analyser (OccAnal) and simplifier (Simplify) treat
      CONLIKE thing like constructors, by ANF-ing them

    - New function GHC.Core.Utils.exprIsExpandable is like exprIsCheap, but
      additionally spots applications of CONLIKE functions

    - A CoreUnfolding has a field that caches exprIsExpandable

    - The rule matcher consults this field.  See
      Note [Expanding variables] in GHC.Core.Rules.

Note [OPAQUE pragma]
~~~~~~~~~~~~~~~~~~~~
Suppose a function `f` is marked {-# OPAQUE f #-}.  Then every call of `f`
should remain a call of `f` throughout optimisation; it should not be turned
into a call of a name-mangled variant of `f` (e.g by worker/wrapper).

The motivation for the OPAQUE pragma is discussed in GHC proposal 0415:
https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0415-opaque-pragma.rst
Basically it boils down to the desire of GHC API users and GHC RULE writers for
calls to certain binders to be left completely untouched by GHCs optimisations.

What this entails at the time of writing, is that for every binder annotated
with the OPAQUE pragma we:

* Do not do worker/wrapper via cast W/W:
  See the guard in GHC.Core.Opt.Simplify.tryCastWorkerWrapper

* Do not any worker/wrapper after demand/CPR analysis. To that end add a guard
  in GHC.Core.Opt.WorkWrap.tryWW to disable worker/wrapper

* It is important that the demand signature and CPR signature do not lie, else
  clients of the function will believe that it has the CPR property etc. But it
  won't, because we've disabled worker/wrapper. To avoid the signatures lying:
  * Strip boxity information from the demand signature
    in GHC.Core.Opt.DmdAnal.finaliseArgBoxities
    See Note [The OPAQUE pragma and avoiding the reboxing of arguments]
  * Strip CPR information from the CPR signature
    in GHC.Core.Opt.CprAnal.cprAnalBind
    See Note [The OPAQUE pragma and avoiding the reboxing of results]

* Do create specialised versions of the function in
  * Specialise: see GHC.Core.Opt.Specialise.specCalls
  * SpecConstr: see GHC.Core.Opt.SpecConstr.specialise
  Both are accomplished easily: these passes already skip NOINLINE
  functions with NeverActive activation, and an OPAQUE function is
  also NeverActive.

At the moment of writing, the major difference between the NOINLINE pragma and
the OPAQUE pragma is that binders annoted with the NOINLINE pragma _are_ W/W
transformed (see also Note [Worker/wrapper for NOINLINE functions]) where
binders annoted with the OPAQUE pragma are _not_ W/W transformed.

Future "name-mangling" optimisations should respect the OPAQUE pragma and
update the list of moving parts referenced in this note.

-}

isConLike :: RuleMatchInfo -> Bool
isConLike :: RuleMatchInfo -> Bool
isConLike RuleMatchInfo
ConLike = Bool
True
isConLike RuleMatchInfo
_       = Bool
False

isFunLike :: RuleMatchInfo -> Bool
isFunLike :: RuleMatchInfo -> Bool
isFunLike RuleMatchInfo
FunLike = Bool
True
isFunLike RuleMatchInfo
_       = Bool
False

noUserInlineSpec :: InlineSpec -> Bool
noUserInlineSpec :: InlineSpec -> Bool
noUserInlineSpec InlineSpec
NoUserInlinePrag = Bool
True
noUserInlineSpec InlineSpec
_                = Bool
False

isInlinePragma :: InlinePragma p -> Bool
isInlinePragma :: forall p. InlinePragma p -> Bool
isInlinePragma = (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall p. (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec ((InlineSpec -> Bool) -> InlinePragma p -> Bool)
-> (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall a b. (a -> b) -> a -> b
$ \case
  InlineSpec
Inline -> Bool
True
  InlineSpec
_      -> Bool
False

isInlinablePragma :: InlinePragma p -> Bool
isInlinablePragma :: forall p. InlinePragma p -> Bool
isInlinablePragma = (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall p. (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec ((InlineSpec -> Bool) -> InlinePragma p -> Bool)
-> (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall a b. (a -> b) -> a -> b
$ \case
  InlineSpec
Inlinable -> Bool
True
  InlineSpec
_         -> Bool
False

isNoInlinePragma :: InlinePragma p -> Bool
isNoInlinePragma :: forall p. InlinePragma p -> Bool
isNoInlinePragma = (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall p. (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec ((InlineSpec -> Bool) -> InlinePragma p -> Bool)
-> (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall a b. (a -> b) -> a -> b
$ \case
  InlineSpec
NoInline -> Bool
True
  InlineSpec
_        -> Bool
False

isAnyInlinePragma :: InlinePragma p -> Bool
-- INLINE or INLINABLE
isAnyInlinePragma :: forall p. InlinePragma p -> Bool
isAnyInlinePragma = (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall p. (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec ((InlineSpec -> Bool) -> InlinePragma p -> Bool)
-> (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall a b. (a -> b) -> a -> b
$ \case
  InlineSpec
Inline    -> Bool
True
  InlineSpec
Inlinable -> Bool
True
  InlineSpec
_         -> Bool
False

isOpaquePragma :: InlinePragma p -> Bool
isOpaquePragma :: forall p. InlinePragma p -> Bool
isOpaquePragma = (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall p. (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec ((InlineSpec -> Bool) -> InlinePragma p -> Bool)
-> (InlineSpec -> Bool) -> InlinePragma p -> Bool
forall a b. (a -> b) -> a -> b
$ \case
  InlineSpec
Opaque -> Bool
True
  InlineSpec
_      -> Bool
False

queryInlineSpec :: (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec :: forall p. (InlineSpec -> Bool) -> InlinePragma p -> Bool
queryInlineSpec InlineSpec -> Bool
_ (XInlinePragma XXInlinePragma p
_) = Bool
False
queryInlineSpec InlineSpec -> Bool
f (InlinePragma { inl_inline :: forall pass. InlinePragma pass -> InlineSpec
inl_inline = InlineSpec
line }) = InlineSpec -> Bool
f InlineSpec
line

-- | Compilation phase number, as can be written by users in INLINE pragmas,
-- SPECIALISE pragmas, and RULES.
--
--   - phases decrease towards zero
--   - zero is the last phase
--
-- Does not include GHC internal "initial" and "final" phases; see 'CompilerPhase'.
type PhaseNum = Int


-- The TTG data type; use this for TTG fields
type Activation pass = ActivationX (XXActivation pass)

-- | An activation is a range of phases throughout which something is active
-- (like an INLINE pragma, SPECIALISE pragma, or RULE).
data ActivationX e
  = AlwaysActive
  -- | Active only *strictly before* this phase
  | ActiveBefore PhaseNum
  -- | Active in this phase and later phases
  | ActiveAfter  PhaseNum
  -- | Active in the final phase only
  | NeverActive
  | XActivation !e

deriving instance Eq e => Eq (ActivationX e)
  -- Eq used in comparing rules in GHC.Hs.Decls

instance NFData e => NFData (ActivationX e) where
  rnf :: ActivationX e -> ()
rnf = \case
    ActivationX e
AlwaysActive -> ()
    ActivationX e
NeverActive -> ()
    ActiveBefore Int
aa -> Int -> ()
forall a. NFData a => a -> ()
rnf Int
aa
    ActiveAfter Int
ab -> Int -> ()
forall a. NFData a => a -> ()
rnf Int
ab
    XActivation e
x -> e -> ()
forall a. NFData a => a -> ()
rnf e
x () -> () -> ()
forall a b. a -> b -> b
`seq` ()