{-# LANGUAGE LambdaCase #-}

{-
   these are needed for the Outputable instance for GenTickish,
   since we need XTickishId to be Outputable. This should immediately
   resolve to something like Id.
 -}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}

{-
(c) The University of Glasgow 2006
(c) The AQUA Project, Glasgow University, 1996-1998


Printing of Core syntax
-}

module GHC.Core.Ppr (
        pprCoreExpr, pprParendExpr,
        pprCoreBinding, pprCoreBindings, pprCoreAlt,
        pprCoreBindingWithSize, pprCoreBindingsWithSize,
        pprCoreBinder, pprCoreBinders, pprId, pprIds,
        pprRule, pprRules, pprOptCo,
        pprOcc, pprOccWithTick
    ) where

import GHC.Prelude

import GHC.Core
import GHC.Core.Stats (exprStats)
import GHC.Types.Fixity (LexicalFixity(..))
import GHC.Types.Literal( pprLiteral )
import GHC.Types.Name( pprInfixName, pprPrefixName )
import GHC.Types.Var
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Types.Demand
import GHC.Types.Cpr
import GHC.Core.DataCon
import GHC.Core.TyCon
import GHC.Core.TyCo.Ppr
import GHC.Core.Coercion
import GHC.Types.Basic
import GHC.Data.Maybe
import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Types.SrcLoc ( pprUserRealSpan )
import GHC.Types.Tickish

{-
************************************************************************
*                                                                      *
\subsection{Public interfaces for Core printing (excluding instances)}
*                                                                      *
************************************************************************

@pprParendCoreExpr@ puts parens around non-atomic Core expressions.
-}

pprCoreBindings :: OutputableBndr b => [Bind b] -> SDoc
pprCoreBinding  :: OutputableBndr b => Bind b  -> SDoc
pprCoreExpr     :: OutputableBndr b => Expr b  -> SDoc
pprParendExpr   :: OutputableBndr b => Expr b  -> SDoc

pprCoreBindings :: forall b. OutputableBndr b => [Bind b] -> SDoc
pprCoreBindings = forall a. OutputableBndr a => Annotation a -> [Bind a] -> SDoc
pprTopBinds forall b. Expr b -> SDoc
noAnn
pprCoreBinding :: forall b. OutputableBndr b => Bind b -> SDoc
pprCoreBinding  = forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
pprTopBind forall b. Expr b -> SDoc
noAnn

pprCoreBindingsWithSize :: [CoreBind] -> SDoc
pprCoreBindingWithSize  :: CoreBind  -> SDoc

pprCoreBindingsWithSize :: [CoreBind] -> SDoc
pprCoreBindingsWithSize = forall a. OutputableBndr a => Annotation a -> [Bind a] -> SDoc
pprTopBinds CoreExpr -> SDoc
sizeAnn
pprCoreBindingWithSize :: CoreBind -> SDoc
pprCoreBindingWithSize = forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
pprTopBind CoreExpr -> SDoc
sizeAnn

instance OutputableBndr b => Outputable (Bind b) where
    ppr :: Bind b -> SDoc
ppr Bind b
bind = forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
ppr_bind forall b. Expr b -> SDoc
noAnn Bind b
bind

instance OutputableBndr b => Outputable (Expr b) where
    ppr :: Expr b -> SDoc
ppr Expr b
expr = forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
expr

instance OutputableBndr b => Outputable (Alt b) where
    ppr :: Alt b -> SDoc
ppr Alt b
expr = forall b. OutputableBndr b => Alt b -> SDoc
pprCoreAlt Alt b
expr

{-
************************************************************************
*                                                                      *
\subsection{The guts}
*                                                                      *
************************************************************************
-}

-- | A function to produce an annotation for a given right-hand-side
type Annotation b = Expr b -> SDoc

-- | Annotate with the size of the right-hand-side
sizeAnn :: CoreExpr -> SDoc
sizeAnn :: CoreExpr -> SDoc
sizeAnn CoreExpr
e = forall doc. IsLine doc => String -> doc
text String
"-- RHS size:" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr (CoreExpr -> CoreStats
exprStats CoreExpr
e)

-- | No annotation
noAnn :: Expr b -> SDoc
noAnn :: forall b. Expr b -> SDoc
noAnn Expr b
_ = forall doc. IsOutput doc => doc
empty

pprTopBinds :: OutputableBndr a
            => Annotation a -- ^ generate an annotation to place before the
                            -- binding
            -> [Bind a]     -- ^ bindings to show
            -> SDoc         -- ^ the pretty result
pprTopBinds :: forall a. OutputableBndr a => Annotation a -> [Bind a] -> SDoc
pprTopBinds Annotation a
ann [Bind a]
binds = forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
pprTopBind Annotation a
ann) [Bind a]
binds)

pprTopBind :: OutputableBndr a => Annotation a -> Bind a -> SDoc
pprTopBind :: forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
pprTopBind Annotation a
ann (NonRec a
binder Expr a
expr)
 = forall b. OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding Annotation a
ann (a
binder,Expr a
expr) forall doc. IsDoc doc => doc -> doc -> doc
$$ SDoc
blankLine

pprTopBind Annotation a
_ (Rec [])
  = forall doc. IsLine doc => String -> doc
text String
"Rec { }"
pprTopBind Annotation a
ann (Rec ((a, Expr a)
b:[(a, Expr a)]
bs))
  = forall doc. IsDoc doc => [doc] -> doc
vcat [forall doc. IsLine doc => String -> doc
text String
"Rec {",
          forall b. OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding Annotation a
ann (a, Expr a)
b,
          forall doc. IsDoc doc => [doc] -> doc
vcat [SDoc
blankLine forall doc. IsDoc doc => doc -> doc -> doc
$$ forall b. OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding Annotation a
ann (a, Expr a)
b | (a, Expr a)
b <- [(a, Expr a)]
bs],
          forall doc. IsLine doc => String -> doc
text String
"end Rec }",
          SDoc
blankLine]

ppr_bind :: OutputableBndr b => Annotation b -> Bind b -> SDoc

ppr_bind :: forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
ppr_bind Annotation b
ann (NonRec b
val_bdr Expr b
expr) = forall b. OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding Annotation b
ann (b
val_bdr, Expr b
expr)
ppr_bind Annotation b
ann (Rec [(b, Expr b)]
binds)           = forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (b, Expr b) -> SDoc
pp [(b, Expr b)]
binds)
                                    where
                                      pp :: (b, Expr b) -> SDoc
pp (b, Expr b)
bind = forall b. OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding Annotation b
ann (b, Expr b)
bind forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
semi

ppr_binding :: OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding :: forall b. OutputableBndr b => Annotation b -> (b, Expr b) -> SDoc
ppr_binding Annotation b
ann (b
val_bdr, Expr b
expr)
  = forall doc. IsDoc doc => [doc] -> doc
vcat [ Annotation b
ann Expr b
expr
         , forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressTypeSignatures
             (forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind b
val_bdr)
         , SDoc
pp_bind
         ]
  where
    pp_val_bdr :: SDoc
pp_val_bdr = forall a. OutputableBndr a => a -> SDoc
pprPrefixOcc b
val_bdr

    pp_bind :: SDoc
pp_bind = case forall a. OutputableBndr a => a -> Maybe ArityInfo
bndrIsJoin_maybe b
val_bdr of
                Maybe ArityInfo
Nothing -> SDoc
pp_normal_bind
                Just ArityInfo
ar -> ArityInfo -> SDoc
pp_join_bind ArityInfo
ar

    pp_normal_bind :: SDoc
pp_normal_bind = SDoc -> ArityInfo -> SDoc -> SDoc
hang SDoc
pp_val_bdr ArityInfo
2 (forall doc. IsLine doc => doc
equals forall doc. IsLine doc => doc -> doc -> doc
<+> forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
expr)

      -- For a join point of join arity n, we want to print j = \x1 ... xn -> e
      -- as "j x1 ... xn = e" to differentiate when a join point returns a
      -- lambda (the first rendering looks like a nullary join point returning
      -- an n-argument function).
    pp_join_bind :: ArityInfo -> SDoc
pp_join_bind ArityInfo
join_arity
      | [b]
bndrs forall a. [a] -> ArityInfo -> Bool
`lengthAtLeast` ArityInfo
join_arity
      = SDoc -> ArityInfo -> SDoc -> SDoc
hang (SDoc
pp_val_bdr forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map (forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LambdaBind) [b]
lhs_bndrs))
           ArityInfo
2 (forall doc. IsLine doc => doc
equals forall doc. IsLine doc => doc -> doc -> doc
<+> forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
rhs)
      | Bool
otherwise -- Yikes!  A join-binding with too few lambda
                  -- Lint will complain, but we don't want to crash
                  -- the pretty-printer else we can't see what's wrong
                  -- So refer to printing  j = e
      = SDoc
pp_normal_bind
      where
        ([b]
bndrs, Expr b
body) = forall b. Expr b -> ([b], Expr b)
collectBinders Expr b
expr
        lhs_bndrs :: [b]
lhs_bndrs = forall a. ArityInfo -> [a] -> [a]
take ArityInfo
join_arity [b]
bndrs
        rhs :: Expr b
rhs       = forall b. [b] -> Expr b -> Expr b
mkLams (forall a. ArityInfo -> [a] -> [a]
drop ArityInfo
join_arity [b]
bndrs) Expr b
body

pprParendExpr :: forall b. OutputableBndr b => Expr b -> SDoc
pprParendExpr Expr b
expr = forall b. OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc
ppr_expr forall doc. IsLine doc => doc -> doc
parens Expr b
expr
pprCoreExpr :: forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr   Expr b
expr = forall b. OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc
ppr_expr SDoc -> SDoc
noParens Expr b
expr

noParens :: SDoc -> SDoc
noParens :: SDoc -> SDoc
noParens SDoc
pp = SDoc
pp

pprOptCo :: Coercion -> SDoc
-- Print a coercion optionally; i.e. honouring -dsuppress-coercions
pprOptCo :: Coercion -> SDoc
pprOptCo Coercion
co = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressCoercions forall a b. (a -> b) -> a -> b
$ \case
              Bool
True  -> forall doc. IsLine doc => doc -> doc
angleBrackets (forall doc. IsLine doc => String -> doc
text String
"Co:" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => ArityInfo -> doc
int (Coercion -> ArityInfo
coercionSize Coercion
co)) forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
co_type
              Bool
False -> forall doc. IsLine doc => doc -> doc
parens forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
sep [forall a. Outputable a => a -> SDoc
ppr Coercion
co, SDoc
dcolon forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
co_type]
    where
      co_type :: SDoc
co_type = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressCoercionTypes forall a b. (a -> b) -> a -> b
$ \case
          Bool
True -> forall doc. IsLine doc => String -> doc
text String
"..."
          Bool
False -> forall a. Outputable a => a -> SDoc
ppr (Coercion -> Kind
coercionType Coercion
co)

ppr_id_occ :: (SDoc -> SDoc) -> Id -> SDoc
ppr_id_occ :: (SDoc -> SDoc) -> Id -> SDoc
ppr_id_occ SDoc -> SDoc
add_par Id
id
  | Id -> Bool
isJoinId Id
id = SDoc -> SDoc
add_par ((forall doc. IsLine doc => String -> doc
text String
"jump") forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
pp_id)
  | Bool
otherwise   = SDoc
pp_id
  where
    pp_id :: SDoc
pp_id = forall a. Outputable a => a -> SDoc
ppr Id
id  -- We could use pprPrefixOcc to print (+) etc, but this is
                    -- Core where we don't print things infix anyway, so doing
                    -- so just adds extra redundant parens

ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc
        -- The function adds parens in context that need
        -- an atomic value (e.g. function args)

ppr_expr :: forall b. OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc
ppr_expr SDoc -> SDoc
add_par (Var Id
id)      = (SDoc -> SDoc) -> Id -> SDoc
ppr_id_occ SDoc -> SDoc
add_par Id
id
ppr_expr SDoc -> SDoc
add_par (Type Kind
ty)     = SDoc -> SDoc
add_par (forall doc. IsLine doc => String -> doc
text String
"TYPE:" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Kind
ty)       -- Weird
ppr_expr SDoc -> SDoc
add_par (Coercion Coercion
co) = SDoc -> SDoc
add_par (forall doc. IsLine doc => String -> doc
text String
"CO:" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Coercion
co)
ppr_expr SDoc -> SDoc
add_par (Lit Literal
lit)     = (SDoc -> SDoc) -> Literal -> SDoc
pprLiteral SDoc -> SDoc
add_par Literal
lit

ppr_expr SDoc -> SDoc
add_par (Cast Expr b
expr Coercion
co)
  = SDoc -> SDoc
add_par forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
sep [forall b. OutputableBndr b => Expr b -> SDoc
pprParendExpr Expr b
expr, forall doc. IsLine doc => String -> doc
text String
"`cast`" forall doc. IsLine doc => doc -> doc -> doc
<+> Coercion -> SDoc
pprOptCo Coercion
co]

ppr_expr SDoc -> SDoc
add_par expr :: Expr b
expr@(Lam b
_ Expr b
_)
  = let
        ([b]
bndrs, Expr b
body) = forall b. Expr b -> ([b], Expr b)
collectBinders Expr b
expr
    in
    SDoc -> SDoc
add_par forall a b. (a -> b) -> a -> b
$
    SDoc -> ArityInfo -> SDoc -> SDoc
hang (forall doc. IsLine doc => String -> doc
text String
"\\" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map (forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LambdaBind) [b]
bndrs) forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow)
         ArityInfo
2 (forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
body)

ppr_expr SDoc -> SDoc
add_par expr :: Expr b
expr@(App {})
  = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressTypeApplications forall a b. (a -> b) -> a -> b
$ \Bool
supp_ty_app ->
    case forall b. Expr b -> (Expr b, [Expr b])
collectArgs Expr b
expr of { (Expr b
fun, [Expr b]
args) ->
    let
        pp_args :: SDoc
pp_args     = forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map forall b. OutputableBndr b => Expr b -> SDoc
pprArg [Expr b]
args)
        val_args :: [Expr b]
val_args    = forall a. (a -> Bool) -> [a] -> [a]
dropWhile forall b. Expr b -> Bool
isTypeArg [Expr b]
args   -- Drop the type arguments for tuples
        pp_tup_args :: SDoc
pp_tup_args = forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr [Expr b]
val_args
        args' :: [Expr b]
args'
          | Bool
supp_ty_app = [Expr b]
val_args
          | Bool
otherwise   = [Expr b]
args
        parens :: SDoc -> SDoc
parens
          | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Expr b]
args' = forall a. a -> a
id
          | Bool
otherwise  = SDoc -> SDoc
add_par
    in
    case Expr b
fun of
        Var Id
f -> case Id -> Maybe DataCon
isDataConWorkId_maybe Id
f of
                        -- Notice that we print the *worker*
                        -- for tuples in paren'd format.
                   Just DataCon
dc | Bool
saturated
                           , Just TupleSort
sort <- TyCon -> Maybe TupleSort
tyConTuple_maybe TyCon
tc
                           -> TupleSort -> SDoc -> SDoc
tupleParens TupleSort
sort SDoc
pp_tup_args
                           where
                             tc :: TyCon
tc        = DataCon -> TyCon
dataConTyCon DataCon
dc
                             saturated :: Bool
saturated = [Expr b]
val_args forall a. [a] -> ArityInfo -> Bool
`lengthIs` Id -> ArityInfo
idArity Id
f

                   Maybe DataCon
_ -> SDoc -> SDoc
parens (SDoc -> ArityInfo -> SDoc -> SDoc
hang SDoc
fun_doc ArityInfo
2 SDoc
pp_args)
                   where
                     fun_doc :: SDoc
fun_doc = (SDoc -> SDoc) -> Id -> SDoc
ppr_id_occ SDoc -> SDoc
noParens Id
f

        Expr b
_ -> SDoc -> SDoc
parens (SDoc -> ArityInfo -> SDoc -> SDoc
hang (forall b. OutputableBndr b => Expr b -> SDoc
pprParendExpr Expr b
fun) ArityInfo
2 SDoc
pp_args)
    }

ppr_expr SDoc -> SDoc
add_par (Case Expr b
expr b
var Kind
ty [Alt AltCon
con [b]
args Expr b
rhs])
  = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintCaseAsLet forall a b. (a -> b) -> a -> b
$ \case
      Bool
True -> SDoc -> SDoc
add_par forall a b. (a -> b) -> a -> b
$  -- See Note [Print case as let]
               forall doc. IsLine doc => [doc] -> doc
sep [ forall doc. IsLine doc => [doc] -> doc
sep [ forall doc. IsLine doc => String -> doc
text String
"let! {"
                           forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. OutputableBndr a => AltCon -> [a] -> SDoc
ppr_case_pat AltCon
con [b]
args
                           forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"~"
                           forall doc. IsLine doc => doc -> doc -> doc
<+> b -> SDoc
ppr_bndr b
var
                         , forall doc. IsLine doc => String -> doc
text String
"<-" forall doc. IsLine doc => doc -> doc -> doc
<+> forall b. OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc
ppr_expr forall a. a -> a
id Expr b
expr
                           forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"} in" ]
                   , forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
rhs
                   ]
      Bool
False -> SDoc -> SDoc
add_par forall a b. (a -> b) -> a -> b
$
                forall doc. IsLine doc => [doc] -> doc
sep [forall doc. IsLine doc => [doc] -> doc
sep [forall doc. IsLine doc => [doc] -> doc
sep [ forall doc. IsLine doc => String -> doc
text String
"case" forall doc. IsLine doc => doc -> doc -> doc
<+> forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
expr
                              , forall doc. IsOutput doc => doc -> doc
whenPprDebug (forall doc. IsLine doc => String -> doc
text String
"return" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Kind
ty)
                              , forall doc. IsLine doc => String -> doc
text String
"of" forall doc. IsLine doc => doc -> doc -> doc
<+> b -> SDoc
ppr_bndr b
var
                              ]
                         , forall doc. IsLine doc => Char -> doc
char Char
'{' forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. OutputableBndr a => AltCon -> [a] -> SDoc
ppr_case_pat AltCon
con [b]
args forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow
                         ]
                     , forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
rhs
                     , forall doc. IsLine doc => Char -> doc
char Char
'}'
                     ]
  where
    ppr_bndr :: b -> SDoc
ppr_bndr = forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
CaseBind

ppr_expr SDoc -> SDoc
add_par (Case Expr b
expr b
var Kind
ty [Alt b]
alts)
  = SDoc -> SDoc
add_par forall a b. (a -> b) -> a -> b
$
    forall doc. IsLine doc => [doc] -> doc
sep [forall doc. IsLine doc => [doc] -> doc
sep [forall doc. IsLine doc => String -> doc
text String
"case"
                forall doc. IsLine doc => doc -> doc -> doc
<+> forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
expr
                forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsOutput doc => doc -> doc
whenPprDebug (forall doc. IsLine doc => String -> doc
text String
"return" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Kind
ty),
              forall doc. IsLine doc => String -> doc
text String
"of" forall doc. IsLine doc => doc -> doc -> doc
<+> b -> SDoc
ppr_bndr b
var forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Char -> doc
char Char
'{'],
         ArityInfo -> SDoc -> SDoc
nest ArityInfo
2 (forall doc. IsDoc doc => [doc] -> doc
vcat (forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate forall doc. IsLine doc => doc
semi (forall a b. (a -> b) -> [a] -> [b]
map forall b. OutputableBndr b => Alt b -> SDoc
pprCoreAlt [Alt b]
alts))),
         forall doc. IsLine doc => Char -> doc
char Char
'}'
    ]
  where
    ppr_bndr :: b -> SDoc
ppr_bndr = forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
CaseBind


-- special cases: let ... in let ...
-- ("disgusting" SLPJ)

{-
ppr_expr add_par (Let bind@(NonRec val_bdr rhs@(Let _ _)) body)
  = add_par $
    vcat [
      hsep [text "let {", (pprBndr LetBind val_bdr $$ ppr val_bndr), equals],
      nest 2 (pprCoreExpr rhs),
      text "} in",
      pprCoreExpr body ]

ppr_expr add_par (Let bind@(NonRec val_bdr rhs) expr@(Let _ _))
  = add_par
    (hang (text "let {")
          2 (hsep [ppr_binding (val_bdr,rhs),
                   text "} in"])
     $$
     pprCoreExpr expr)
-}


-- General case (recursive case, too)
ppr_expr SDoc -> SDoc
add_par (Let Bind b
bind Expr b
expr)
  = SDoc -> SDoc
add_par forall a b. (a -> b) -> a -> b
$
    forall doc. IsLine doc => [doc] -> doc
sep [SDoc -> ArityInfo -> SDoc -> SDoc
hang (forall {a} {doc}. (OutputableBndr a, IsLine doc) => Bind a -> doc
keyword Bind b
bind forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Char -> doc
char Char
'{') ArityInfo
2 (forall a. OutputableBndr a => Annotation a -> Bind a -> SDoc
ppr_bind forall b. Expr b -> SDoc
noAnn Bind b
bind forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"} in"),
         forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
expr]
  where
    keyword :: Bind a -> doc
keyword (NonRec a
b Expr a
_)
     | forall a. Maybe a -> Bool
isJust (forall a. OutputableBndr a => a -> Maybe ArityInfo
bndrIsJoin_maybe a
b) = forall doc. IsLine doc => String -> doc
text String
"join"
     | Bool
otherwise                   = forall doc. IsLine doc => String -> doc
text String
"let"
    keyword (Rec [(a, Expr a)]
pairs)
     | ((a
b,Expr a
_):[(a, Expr a)]
_) <- [(a, Expr a)]
pairs
     , forall a. Maybe a -> Bool
isJust (forall a. OutputableBndr a => a -> Maybe ArityInfo
bndrIsJoin_maybe a
b) = forall doc. IsLine doc => String -> doc
text String
"joinrec"
     | Bool
otherwise                   = forall doc. IsLine doc => String -> doc
text String
"letrec"

ppr_expr SDoc -> SDoc
add_par (Tick CoreTickish
tickish Expr b
expr)
  = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressTicks forall a b. (a -> b) -> a -> b
$ \case
      -- Only hide non-runtime relevant ticks.
      Bool
True
        | Bool -> Bool
not (forall (pass :: TickishPass). GenTickish pass -> Bool
tickishIsCode CoreTickish
tickish) -> forall b. OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc
ppr_expr SDoc -> SDoc
add_par Expr b
expr
      Bool
_ -> SDoc -> SDoc
add_par (forall doc. IsLine doc => [doc] -> doc
sep [forall a. Outputable a => a -> SDoc
ppr CoreTickish
tickish, forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
expr])

pprCoreAlt :: OutputableBndr a => Alt a -> SDoc
pprCoreAlt :: forall b. OutputableBndr b => Alt b -> SDoc
pprCoreAlt (Alt AltCon
con [a]
args Expr a
rhs)
  = SDoc -> ArityInfo -> SDoc -> SDoc
hang (forall a. OutputableBndr a => AltCon -> [a] -> SDoc
ppr_case_pat AltCon
con [a]
args forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow) ArityInfo
2 (forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr a
rhs)

ppr_case_pat :: OutputableBndr a => AltCon -> [a] -> SDoc
ppr_case_pat :: forall a. OutputableBndr a => AltCon -> [a] -> SDoc
ppr_case_pat (DataAlt DataCon
dc) [a]
args
  | Just TupleSort
sort <- TyCon -> Maybe TupleSort
tyConTuple_maybe TyCon
tc
  = TupleSort -> SDoc -> SDoc
tupleParens TupleSort
sort (forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas a -> SDoc
ppr_bndr [a]
args)
  where
    ppr_bndr :: a -> SDoc
ppr_bndr = forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
CasePatBind
    tc :: TyCon
tc = DataCon -> TyCon
dataConTyCon DataCon
dc

ppr_case_pat AltCon
con [a]
args
  = forall a. Outputable a => a -> SDoc
ppr AltCon
con forall doc. IsLine doc => doc -> doc -> doc
<+> (forall doc. IsLine doc => [doc] -> doc
fsep (forall a b. (a -> b) -> [a] -> [b]
map a -> SDoc
ppr_bndr [a]
args))
  where
    ppr_bndr :: a -> SDoc
ppr_bndr = forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
CasePatBind


-- | Pretty print the argument in a function application.
pprArg :: OutputableBndr a => Expr a -> SDoc
pprArg :: forall b. OutputableBndr b => Expr b -> SDoc
pprArg (Type Kind
ty)
 = forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressTypeApplications
      (forall doc. IsLine doc => String -> doc
text String
"@" forall doc. IsLine doc => doc -> doc -> doc
<> Kind -> SDoc
pprParendType Kind
ty)
pprArg (Coercion Coercion
co) = forall doc. IsLine doc => String -> doc
text String
"@~" forall doc. IsLine doc => doc -> doc -> doc
<> Coercion -> SDoc
pprOptCo Coercion
co
pprArg Expr a
expr          = forall b. OutputableBndr b => Expr b -> SDoc
pprParendExpr Expr a
expr

{-
Note [Print case as let]
~~~~~~~~~~~~~~~~~~~~~~~~
Single-branch case expressions are very common:
   case x of y { I# x' ->
   case p of q { I# p' -> ... } }
These are, in effect, just strict let's, with pattern matching.
With -dppr-case-as-let we print them as such:
   let! { I# x' ~ y <- x } in
   let! { I# p' ~ q <- p } in ...


Other printing bits-and-bobs used with the general @pprCoreBinding@
and @pprCoreExpr@ functions.


Note [Binding-site specific printing]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pprCoreBinder and pprTypedLamBinder receive a BindingSite argument to adjust
the information printed.

Let-bound binders are printed with their full type and idInfo.

Case-bound variables (both the case binder and pattern variables) are printed
without a type and without their unfolding.

Furthermore, a dead case-binder is completely ignored, while otherwise, dead
binders are printed as "_".
-}

-- These instances are sadly orphans

instance OutputableBndr Var where
  pprBndr :: BindingSite -> Id -> SDoc
pprBndr = BindingSite -> Id -> SDoc
pprCoreBinder
  pprInfixOcc :: Id -> SDoc
pprInfixOcc  = forall a. (Outputable a, NamedThing a) => a -> SDoc
pprInfixName  forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Name
varName
  pprPrefixOcc :: Id -> SDoc
pprPrefixOcc = forall a. NamedThing a => a -> SDoc
pprPrefixName forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Name
varName
  bndrIsJoin_maybe :: Id -> Maybe ArityInfo
bndrIsJoin_maybe = Id -> Maybe ArityInfo
isJoinId_maybe

instance Outputable b => OutputableBndr (TaggedBndr b) where
  pprBndr :: BindingSite -> TaggedBndr b -> SDoc
pprBndr BindingSite
_    TaggedBndr b
b = forall a. Outputable a => a -> SDoc
ppr TaggedBndr b
b   -- Simple
  pprInfixOcc :: TaggedBndr b -> SDoc
pprInfixOcc  TaggedBndr b
b = forall a. Outputable a => a -> SDoc
ppr TaggedBndr b
b
  pprPrefixOcc :: TaggedBndr b -> SDoc
pprPrefixOcc TaggedBndr b
b = forall a. Outputable a => a -> SDoc
ppr TaggedBndr b
b
  bndrIsJoin_maybe :: TaggedBndr b -> Maybe ArityInfo
bndrIsJoin_maybe (TB Id
b b
_) = Id -> Maybe ArityInfo
isJoinId_maybe Id
b

pprOcc :: OutputableBndr a => LexicalFixity -> a -> SDoc
pprOcc :: forall a. OutputableBndr a => LexicalFixity -> a -> SDoc
pprOcc LexicalFixity
Infix  = forall a. OutputableBndr a => a -> SDoc
pprInfixOcc
pprOcc LexicalFixity
Prefix = forall a. OutputableBndr a => a -> SDoc
pprPrefixOcc

pprOccWithTick :: OutputableBndr a => LexicalFixity -> PromotionFlag -> a -> SDoc
pprOccWithTick :: forall a.
OutputableBndr a =>
LexicalFixity -> PromotionFlag -> a -> SDoc
pprOccWithTick LexicalFixity
fixity PromotionFlag
prom a
op
  | PromotionFlag -> Bool
isPromoted PromotionFlag
prom
  = SDoc -> SDoc
quote (forall a. OutputableBndr a => LexicalFixity -> a -> SDoc
pprOcc LexicalFixity
fixity a
op)
  | Bool
otherwise
  = forall a. OutputableBndr a => LexicalFixity -> a -> SDoc
pprOcc LexicalFixity
fixity a
op

pprCoreBinder :: BindingSite -> Var -> SDoc
pprCoreBinder :: BindingSite -> Id -> SDoc
pprCoreBinder BindingSite
LetBind Id
binder
  | Id -> Bool
isTyVar Id
binder = Id -> SDoc
pprKindedTyVarBndr Id
binder
  | Bool
otherwise      = Id -> SDoc
pprTypedLetBinder Id
binder forall doc. IsDoc doc => doc -> doc -> doc
$$
                     Id -> IdInfo -> SDoc
ppIdInfo Id
binder (HasDebugCallStack => Id -> IdInfo
idInfo Id
binder)

-- Lambda bound type variables are preceded by "@"
pprCoreBinder BindingSite
bind_site Id
bndr
  = forall doc. IsOutput doc => (Bool -> doc) -> doc
getPprDebug forall a b. (a -> b) -> a -> b
$ \Bool
debug ->
    BindingSite -> Bool -> Id -> SDoc
pprTypedLamBinder BindingSite
bind_site Bool
debug Id
bndr

pprCoreBinders :: [Var] -> SDoc
-- Print as lambda-binders, i.e. with their type
pprCoreBinders :: [Id] -> SDoc
pprCoreBinders [Id]
vs = forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map (BindingSite -> Id -> SDoc
pprCoreBinder BindingSite
LambdaBind) [Id]
vs)

pprUntypedBinder :: Var -> SDoc
pprUntypedBinder :: Id -> SDoc
pprUntypedBinder Id
binder
  | Id -> Bool
isTyVar Id
binder = forall doc. IsLine doc => String -> doc
text String
"@" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Id
binder    -- NB: don't print kind
  | Bool
otherwise      = Id -> SDoc
pprIdBndr Id
binder

pprTypedLamBinder :: BindingSite -> Bool -> Var -> SDoc
-- For lambda and case binders, show the unfolding info (usually none)
pprTypedLamBinder :: BindingSite -> Bool -> Id -> SDoc
pprTypedLamBinder BindingSite
bind_site Bool
debug_on Id
var
  = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressTypeSignatures forall a b. (a -> b) -> a -> b
$ \Bool
suppress_sigs ->
    case () of
    ()
_
      | Bool -> Bool
not Bool
debug_on            -- Show case-bound wild binders only if debug is on
      , BindingSite
CaseBind <- BindingSite
bind_site
      , Id -> Bool
isDeadBinder Id
var        -> forall doc. IsOutput doc => doc
empty

      | Bool -> Bool
not Bool
debug_on            -- Even dead binders can be one-shot
      , Id -> Bool
isDeadBinder Id
var        -> forall doc. IsLine doc => Char -> doc
char Char
'_' forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsOutput doc => Bool -> doc -> doc
ppWhen (Id -> Bool
isId Id
var)
                                                (IdInfo -> SDoc
pprIdBndrInfo (HasDebugCallStack => Id -> IdInfo
idInfo Id
var))

      | Bool -> Bool
not Bool
debug_on            -- No parens, no kind info
      , BindingSite
CaseBind <- BindingSite
bind_site   -> Id -> SDoc
pprUntypedBinder Id
var

      | Bool -> Bool
not Bool
debug_on
      , BindingSite
CasePatBind <- BindingSite
bind_site    -> Id -> SDoc
pprUntypedBinder Id
var

      | Bool
suppress_sigs -> Id -> SDoc
pprUntypedBinder Id
var

      | Id -> Bool
isTyVar Id
var  -> forall doc. IsLine doc => doc -> doc
parens (Id -> SDoc
pprKindedTyVarBndr Id
var)

      | Bool
otherwise    -> forall doc. IsLine doc => doc -> doc
parens (SDoc -> ArityInfo -> SDoc -> SDoc
hang (Id -> SDoc
pprIdBndr Id
var)
                                   ArityInfo
2 (forall doc. IsDoc doc => [doc] -> doc
vcat [ SDoc
dcolon forall doc. IsLine doc => doc -> doc -> doc
<+> Kind -> SDoc
pprType (Id -> Kind
idType Id
var)
                                           , SDoc
pp_unf]))
  where
    unf_info :: Unfolding
unf_info = IdInfo -> Unfolding
realUnfoldingInfo (HasDebugCallStack => Id -> IdInfo
idInfo Id
var)
    pp_unf :: SDoc
pp_unf | Unfolding -> Bool
hasSomeUnfolding Unfolding
unf_info = forall doc. IsLine doc => String -> doc
text String
"Unf=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Unfolding
unf_info
           | Bool
otherwise                 = forall doc. IsOutput doc => doc
empty

pprTypedLetBinder :: Var -> SDoc
-- Print binder with a type or kind signature (not paren'd)
pprTypedLetBinder :: Id -> SDoc
pprTypedLetBinder Id
binder
  = forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocSuppressTypeSignatures forall a b. (a -> b) -> a -> b
$ \Bool
suppress_sigs ->
    case () of
    ()
_
      | Id -> Bool
isTyVar Id
binder -> Id -> SDoc
pprKindedTyVarBndr Id
binder
      | Bool
suppress_sigs  -> Id -> SDoc
pprIdBndr Id
binder
      | Bool
otherwise      -> SDoc -> ArityInfo -> SDoc -> SDoc
hang (Id -> SDoc
pprIdBndr Id
binder) ArityInfo
2 (SDoc
dcolon forall doc. IsLine doc => doc -> doc -> doc
<+> Kind -> SDoc
pprType (Id -> Kind
idType Id
binder))

pprKindedTyVarBndr :: TyVar -> SDoc
-- Print a type variable binder with its kind (but not if *)
pprKindedTyVarBndr :: Id -> SDoc
pprKindedTyVarBndr Id
tyvar
  = forall doc. IsLine doc => String -> doc
text String
"@" forall doc. IsLine doc => doc -> doc -> doc
<> Id -> SDoc
pprTyVar Id
tyvar

-- pprId x prints x :: ty
pprId :: Id -> SDoc
pprId :: Id -> SDoc
pprId Id
x = forall a. Outputable a => a -> SDoc
ppr Id
x forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr (Id -> Kind
idType Id
x)

pprIds :: [Id] -> SDoc
pprIds :: [Id] -> SDoc
pprIds [Id]
xs = forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map Id -> SDoc
pprId [Id]
xs)

-- pprIdBndr does *not* print the type
-- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness
pprIdBndr :: Id -> SDoc
pprIdBndr :: Id -> SDoc
pprIdBndr Id
id = forall a. OutputableBndr a => a -> SDoc
pprPrefixOcc Id
id forall doc. IsLine doc => doc -> doc -> doc
<+> IdInfo -> SDoc
pprIdBndrInfo (HasDebugCallStack => Id -> IdInfo
idInfo Id
id)

pprIdBndrInfo :: IdInfo -> SDoc
pprIdBndrInfo :: IdInfo -> SDoc
pprIdBndrInfo IdInfo
info
  = forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressIdInfo
      (IdInfo
info seq :: forall a b. a -> b -> b
`seq` SDoc
doc) -- The seq is useful for poking on black holes
  where
    prag_info :: InlinePragma
prag_info = IdInfo -> InlinePragma
inlinePragInfo IdInfo
info
    occ_info :: OccInfo
occ_info  = IdInfo -> OccInfo
occInfo IdInfo
info
    dmd_info :: Demand
dmd_info  = IdInfo -> Demand
demandInfo IdInfo
info
    lbv_info :: OneShotInfo
lbv_info  = IdInfo -> OneShotInfo
oneShotInfo IdInfo
info

    has_prag :: Bool
has_prag  = Bool -> Bool
not (InlinePragma -> Bool
isDefaultInlinePragma InlinePragma
prag_info)
    has_occ :: Bool
has_occ   = Bool -> Bool
not (OccInfo -> Bool
isNoOccInfo OccInfo
occ_info)
    has_dmd :: Bool
has_dmd   = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Demand -> Bool
isTopDmd Demand
dmd_info
    has_lbv :: Bool
has_lbv   = Bool -> Bool
not (OneShotInfo -> Bool
hasNoOneShotInfo OneShotInfo
lbv_info)

    doc :: SDoc
doc = [(Bool, SDoc)] -> SDoc
showAttributes
          [ (Bool
has_prag, forall doc. IsLine doc => String -> doc
text String
"InlPrag=" forall doc. IsLine doc => doc -> doc -> doc
<> InlinePragma -> SDoc
pprInlineDebug InlinePragma
prag_info)
          , (Bool
has_occ,  forall doc. IsLine doc => String -> doc
text String
"Occ=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr OccInfo
occ_info)
          , (Bool
has_dmd,  forall doc. IsLine doc => String -> doc
text String
"Dmd=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Demand
dmd_info)
          , (Bool
has_lbv , forall doc. IsLine doc => String -> doc
text String
"OS=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr OneShotInfo
lbv_info)
          ]

instance Outputable IdInfo where
  ppr :: IdInfo -> SDoc
ppr IdInfo
info = [(Bool, SDoc)] -> SDoc
showAttributes
    [ (Bool
has_prag,         forall doc. IsLine doc => String -> doc
text String
"InlPrag=" forall doc. IsLine doc => doc -> doc -> doc
<> InlinePragma -> SDoc
pprInlineDebug InlinePragma
prag_info)
    , (Bool
has_occ,          forall doc. IsLine doc => String -> doc
text String
"Occ=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr OccInfo
occ_info)
    , (Bool
has_dmd,          forall doc. IsLine doc => String -> doc
text String
"Dmd=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Demand
dmd_info)
    , (Bool
has_lbv ,         forall doc. IsLine doc => String -> doc
text String
"OS=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr OneShotInfo
lbv_info)
    , (Bool
has_arity,        forall doc. IsLine doc => String -> doc
text String
"Arity=" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
arity)
    , (Bool
has_called_arity, forall doc. IsLine doc => String -> doc
text String
"CallArity=" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
called_arity)
    , (Bool
has_caf_info,     forall doc. IsLine doc => String -> doc
text String
"Caf=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr CafInfo
caf_info)
    , (Bool
has_str_info,     forall doc. IsLine doc => String -> doc
text String
"Str=" forall doc. IsLine doc => doc -> doc -> doc
<> DmdSig -> SDoc
pprStrictness DmdSig
str_info)
    , (Bool
has_unf,          forall doc. IsLine doc => String -> doc
text String
"Unf=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Unfolding
unf_info)
    , (Bool
has_rules,        forall doc. IsLine doc => String -> doc
text String
"RULES:" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map CoreRule -> SDoc
pprRule [CoreRule]
rules))
    ]
    where
      prag_info :: InlinePragma
prag_info = IdInfo -> InlinePragma
inlinePragInfo IdInfo
info
      has_prag :: Bool
has_prag  = Bool -> Bool
not (InlinePragma -> Bool
isDefaultInlinePragma InlinePragma
prag_info)

      occ_info :: OccInfo
occ_info  = IdInfo -> OccInfo
occInfo IdInfo
info
      has_occ :: Bool
has_occ   = Bool -> Bool
not (OccInfo -> Bool
isManyOccs OccInfo
occ_info)

      dmd_info :: Demand
dmd_info  = IdInfo -> Demand
demandInfo IdInfo
info
      has_dmd :: Bool
has_dmd   = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Demand -> Bool
isTopDmd Demand
dmd_info

      lbv_info :: OneShotInfo
lbv_info  = IdInfo -> OneShotInfo
oneShotInfo IdInfo
info
      has_lbv :: Bool
has_lbv   = Bool -> Bool
not (OneShotInfo -> Bool
hasNoOneShotInfo OneShotInfo
lbv_info)

      arity :: ArityInfo
arity = IdInfo -> ArityInfo
arityInfo IdInfo
info
      has_arity :: Bool
has_arity = ArityInfo
arity forall a. Eq a => a -> a -> Bool
/= ArityInfo
0

      called_arity :: ArityInfo
called_arity = IdInfo -> ArityInfo
callArityInfo IdInfo
info
      has_called_arity :: Bool
has_called_arity = ArityInfo
called_arity forall a. Eq a => a -> a -> Bool
/= ArityInfo
0

      caf_info :: CafInfo
caf_info = IdInfo -> CafInfo
cafInfo IdInfo
info
      has_caf_info :: Bool
has_caf_info = Bool -> Bool
not (CafInfo -> Bool
mayHaveCafRefs CafInfo
caf_info)

      str_info :: DmdSig
str_info = IdInfo -> DmdSig
dmdSigInfo IdInfo
info
      has_str_info :: Bool
has_str_info = Bool -> Bool
not (DmdSig -> Bool
isNopSig DmdSig
str_info)

      unf_info :: Unfolding
unf_info = IdInfo -> Unfolding
realUnfoldingInfo IdInfo
info
      has_unf :: Bool
has_unf = Unfolding -> Bool
hasSomeUnfolding Unfolding
unf_info

      rules :: [CoreRule]
rules = RuleInfo -> [CoreRule]
ruleInfoRules (IdInfo -> RuleInfo
ruleInfo IdInfo
info)
      has_rules :: Bool
has_rules = Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
rules)

{-
-----------------------------------------------------
--      IdDetails and IdInfo
-----------------------------------------------------
-}

ppIdInfo :: Id -> IdInfo -> SDoc
ppIdInfo :: Id -> IdInfo -> SDoc
ppIdInfo Id
id IdInfo
info
  = forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressIdInfo forall a b. (a -> b) -> a -> b
$
    [(Bool, SDoc)] -> SDoc
showAttributes
    [ (Bool
True, SDoc
pp_scope forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr (Id -> IdDetails
idDetails Id
id))
    , (Bool
has_arity,        forall doc. IsLine doc => String -> doc
text String
"Arity=" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
arity)
    , (Bool
has_called_arity, forall doc. IsLine doc => String -> doc
text String
"CallArity=" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
called_arity)
    , (Bool
has_caf_info,     forall doc. IsLine doc => String -> doc
text String
"Caf=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr CafInfo
caf_info)
    , (Bool
has_str_info,     forall doc. IsLine doc => String -> doc
text String
"Str=" forall doc. IsLine doc => doc -> doc -> doc
<> DmdSig -> SDoc
pprStrictness DmdSig
str_info)
    , (Bool
has_cpr_info,     forall doc. IsLine doc => String -> doc
text String
"Cpr=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr CprSig
cpr_info)
    , (Bool
has_unf,          forall doc. IsLine doc => String -> doc
text String
"Unf=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Unfolding
unf_info)
    , (Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
rules), forall doc. IsLine doc => String -> doc
text String
"RULES:" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map CoreRule -> SDoc
pprRule [CoreRule]
rules))
    ]   -- Inline pragma, occ, demand, one-shot info
        -- printed out with all binders (when debug is on);
        -- see GHC.Core.Ppr.pprIdBndr
  where
    pp_scope :: SDoc
pp_scope | Id -> Bool
isGlobalId Id
id   = forall doc. IsLine doc => String -> doc
text String
"GblId"
             | Id -> Bool
isExportedId Id
id = forall doc. IsLine doc => String -> doc
text String
"LclIdX"
             | Bool
otherwise       = forall doc. IsLine doc => String -> doc
text String
"LclId"

    arity :: ArityInfo
arity = IdInfo -> ArityInfo
arityInfo IdInfo
info
    has_arity :: Bool
has_arity = ArityInfo
arity forall a. Eq a => a -> a -> Bool
/= ArityInfo
0

    called_arity :: ArityInfo
called_arity = IdInfo -> ArityInfo
callArityInfo IdInfo
info
    has_called_arity :: Bool
has_called_arity = ArityInfo
called_arity forall a. Eq a => a -> a -> Bool
/= ArityInfo
0

    caf_info :: CafInfo
caf_info = IdInfo -> CafInfo
cafInfo IdInfo
info
    has_caf_info :: Bool
has_caf_info = Bool -> Bool
not (CafInfo -> Bool
mayHaveCafRefs CafInfo
caf_info)

    str_info :: DmdSig
str_info = IdInfo -> DmdSig
dmdSigInfo IdInfo
info
    has_str_info :: Bool
has_str_info = Bool -> Bool
not (DmdSig -> Bool
isNopSig DmdSig
str_info)

    cpr_info :: CprSig
cpr_info = IdInfo -> CprSig
cprSigInfo IdInfo
info
    has_cpr_info :: Bool
has_cpr_info = CprSig
cpr_info forall a. Eq a => a -> a -> Bool
/= CprSig
topCprSig

    unf_info :: Unfolding
unf_info = IdInfo -> Unfolding
realUnfoldingInfo IdInfo
info
    has_unf :: Bool
has_unf = Unfolding -> Bool
hasSomeUnfolding Unfolding
unf_info

    rules :: [CoreRule]
rules = RuleInfo -> [CoreRule]
ruleInfoRules (IdInfo -> RuleInfo
ruleInfo IdInfo
info)

showAttributes :: [(Bool,SDoc)] -> SDoc
showAttributes :: [(Bool, SDoc)] -> SDoc
showAttributes [(Bool, SDoc)]
stuff
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SDoc]
docs = forall doc. IsOutput doc => doc
empty
  | Bool
otherwise = forall doc. IsLine doc => doc -> doc
brackets (forall doc. IsLine doc => [doc] -> doc
sep (forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate forall doc. IsLine doc => doc
comma [SDoc]
docs))
  where
    docs :: [SDoc]
docs = [SDoc
d | (Bool
True,SDoc
d) <- [(Bool, SDoc)]
stuff]

{-
-----------------------------------------------------
--      Unfolding and UnfoldingGuidance
-----------------------------------------------------
-}

instance Outputable UnfoldingGuidance where
    ppr :: UnfoldingGuidance -> SDoc
ppr UnfoldingGuidance
UnfNever  = forall doc. IsLine doc => String -> doc
text String
"NEVER"
    ppr (UnfWhen { ug_arity :: UnfoldingGuidance -> ArityInfo
ug_arity = ArityInfo
arity, ug_unsat_ok :: UnfoldingGuidance -> Bool
ug_unsat_ok = Bool
unsat_ok, ug_boring_ok :: UnfoldingGuidance -> Bool
ug_boring_ok = Bool
boring_ok })
      = forall doc. IsLine doc => String -> doc
text String
"ALWAYS_IF" forall doc. IsLine doc => doc -> doc -> doc
<>
        forall doc. IsLine doc => doc -> doc
parens (forall doc. IsLine doc => String -> doc
text String
"arity="     forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
arity    forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
comma forall doc. IsLine doc => doc -> doc -> doc
<>
                forall doc. IsLine doc => String -> doc
text String
"unsat_ok="  forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
unsat_ok forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
comma forall doc. IsLine doc => doc -> doc -> doc
<>
                forall doc. IsLine doc => String -> doc
text String
"boring_ok=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
boring_ok)
    ppr (UnfIfGoodArgs { ug_args :: UnfoldingGuidance -> [ArityInfo]
ug_args = [ArityInfo]
cs, ug_size :: UnfoldingGuidance -> ArityInfo
ug_size = ArityInfo
size, ug_res :: UnfoldingGuidance -> ArityInfo
ug_res = ArityInfo
discount })
      = forall doc. IsLine doc => [doc] -> doc
hsep [ forall doc. IsLine doc => String -> doc
text String
"IF_ARGS",
               forall doc. IsLine doc => doc -> doc
brackets (forall doc. IsLine doc => [doc] -> doc
hsep (forall a b. (a -> b) -> [a] -> [b]
map forall doc. IsLine doc => ArityInfo -> doc
int [ArityInfo]
cs)),
               forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
size,
               forall doc. IsLine doc => ArityInfo -> doc
int ArityInfo
discount ]

instance Outputable Unfolding where
  ppr :: Unfolding -> SDoc
ppr Unfolding
NoUnfolding                = forall doc. IsLine doc => String -> doc
text String
"No unfolding"
  ppr Unfolding
BootUnfolding              = forall doc. IsLine doc => String -> doc
text String
"No unfolding (from boot)"
  ppr (OtherCon [AltCon]
cs)              = forall doc. IsLine doc => String -> doc
text String
"OtherCon" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr [AltCon]
cs
  ppr (DFunUnfolding { df_bndrs :: Unfolding -> [Id]
df_bndrs = [Id]
bndrs, df_con :: Unfolding -> DataCon
df_con = DataCon
con, df_args :: Unfolding -> [CoreExpr]
df_args = [CoreExpr]
args })
       = SDoc -> ArityInfo -> SDoc -> SDoc
hang (forall doc. IsLine doc => String -> doc
text String
"DFun:" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Char -> doc
char Char
'\\'
                forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map (forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LambdaBind) [Id]
bndrs) forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow)
            ArityInfo
2 (forall a. Outputable a => a -> SDoc
ppr DataCon
con forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> SDoc
ppr [CoreExpr]
args))
  ppr (CoreUnfolding { uf_src :: Unfolding -> UnfoldingSource
uf_src = UnfoldingSource
src
                     , uf_tmpl :: Unfolding -> CoreExpr
uf_tmpl=CoreExpr
rhs, uf_is_top :: Unfolding -> Bool
uf_is_top=Bool
top
                     , uf_cache :: Unfolding -> UnfoldingCache
uf_cache=UnfoldingCache
cache, uf_guidance :: Unfolding -> UnfoldingGuidance
uf_guidance=UnfoldingGuidance
g })
        = forall doc. IsLine doc => String -> doc
text String
"Unf" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc -> doc
braces (SDoc
pp_info forall doc. IsDoc doc => doc -> doc -> doc
$$ SDoc
pp_rhs)
    where
      pp_info :: SDoc
pp_info = forall doc. IsLine doc => [doc] -> doc
fsep forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate forall doc. IsLine doc => doc
comma
                [ forall doc. IsLine doc => String -> doc
text String
"Src="        forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr UnfoldingSource
src
                , forall doc. IsLine doc => String -> doc
text String
"TopLvl="     forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
top
                , forall a. Outputable a => a -> SDoc
ppr UnfoldingCache
cache
                , forall doc. IsLine doc => String -> doc
text String
"Guidance="   forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr UnfoldingGuidance
g ]
      pp_tmpl :: SDoc
pp_tmpl = forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressUnfoldings
                  (forall doc. IsLine doc => String -> doc
text String
"Tmpl=" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr CoreExpr
rhs)
      pp_rhs :: SDoc
pp_rhs | UnfoldingSource -> Bool
isStableSource UnfoldingSource
src = SDoc
pp_tmpl
             | Bool
otherwise          = forall doc. IsOutput doc => doc
empty
            -- Don't print the RHS or we get a quadratic
            -- blowup in the size of the printout!

instance Outputable UnfoldingCache where
    ppr :: UnfoldingCache -> SDoc
ppr (UnfoldingCache { uf_is_value :: UnfoldingCache -> Bool
uf_is_value = Bool
hnf, uf_is_conlike :: UnfoldingCache -> Bool
uf_is_conlike = Bool
conlike
                        , uf_is_work_free :: UnfoldingCache -> Bool
uf_is_work_free = Bool
wf, uf_expandable :: UnfoldingCache -> Bool
uf_expandable = Bool
exp })
        = forall doc. IsLine doc => [doc] -> doc
fsep forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate forall doc. IsLine doc => doc
comma
          [ forall doc. IsLine doc => String -> doc
text String
"Value="      forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
hnf
          , forall doc. IsLine doc => String -> doc
text String
"ConLike="    forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
conlike
          , forall doc. IsLine doc => String -> doc
text String
"WorkFree="   forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
wf
          , forall doc. IsLine doc => String -> doc
text String
"Expandable=" forall doc. IsLine doc => doc -> doc -> doc
<> forall a. Outputable a => a -> SDoc
ppr Bool
exp ]

{-
-----------------------------------------------------
--      Rules
-----------------------------------------------------
-}

instance Outputable CoreRule where
   ppr :: CoreRule -> SDoc
ppr = CoreRule -> SDoc
pprRule

pprRules :: [CoreRule] -> SDoc
pprRules :: [CoreRule] -> SDoc
pprRules [CoreRule]
rules = forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map CoreRule -> SDoc
pprRule [CoreRule]
rules)

pprRule :: CoreRule -> SDoc
pprRule :: CoreRule -> SDoc
pprRule (BuiltinRule { ru_fn :: CoreRule -> Name
ru_fn = Name
fn, ru_name :: CoreRule -> RuleName
ru_name = RuleName
name})
  = forall doc. IsLine doc => String -> doc
text String
"Built in rule for" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Name
fn forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
colon forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => doc -> doc
doubleQuotes (forall doc. IsLine doc => RuleName -> doc
ftext RuleName
name)

pprRule (Rule { ru_name :: CoreRule -> RuleName
ru_name = RuleName
name, ru_act :: CoreRule -> Activation
ru_act = Activation
act, ru_fn :: CoreRule -> Name
ru_fn = Name
fn,
                ru_bndrs :: CoreRule -> [Id]
ru_bndrs = [Id]
tpl_vars, ru_args :: CoreRule -> [CoreExpr]
ru_args = [CoreExpr]
tpl_args,
                ru_rhs :: CoreRule -> CoreExpr
ru_rhs = CoreExpr
rhs })
  = SDoc -> ArityInfo -> SDoc -> SDoc
hang (forall doc. IsLine doc => doc -> doc
doubleQuotes (forall doc. IsLine doc => RuleName -> doc
ftext RuleName
name) forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Activation
act)
       ArityInfo
4 (forall doc. IsLine doc => [doc] -> doc
sep [forall doc. IsLine doc => String -> doc
text String
"forall" forall doc. IsLine doc => doc -> doc -> doc
<+> [Id] -> SDoc
pprCoreBinders [Id]
tpl_vars forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
dot,
               ArityInfo -> SDoc -> SDoc
nest ArityInfo
2 (forall a. Outputable a => a -> SDoc
ppr Name
fn forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => [doc] -> doc
sep (forall a b. (a -> b) -> [a] -> [b]
map forall b. OutputableBndr b => Expr b -> SDoc
pprArg [CoreExpr]
tpl_args)),
               ArityInfo -> SDoc -> SDoc
nest ArityInfo
2 (forall doc. IsLine doc => String -> doc
text String
"=" forall doc. IsLine doc => doc -> doc -> doc
<+> forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
rhs)
            ])

{-
-----------------------------------------------------
--      Tickish
-----------------------------------------------------
-}

instance Outputable (XTickishId pass) => Outputable (GenTickish pass) where
  ppr :: GenTickish pass -> SDoc
ppr (HpcTick Module
modl ArityInfo
ix) =
      forall doc. IsLine doc => [doc] -> doc
hcat [forall doc. IsLine doc => String -> doc
text String
"hpc<",
            forall a. Outputable a => a -> SDoc
ppr Module
modl, forall doc. IsLine doc => doc
comma,
            forall a. Outputable a => a -> SDoc
ppr ArityInfo
ix,
            forall doc. IsLine doc => String -> doc
text String
">"]
  ppr (Breakpoint XBreakpoint pass
_ext ArityInfo
ix [XTickishId pass]
vars) =
      forall doc. IsLine doc => [doc] -> doc
hcat [forall doc. IsLine doc => String -> doc
text String
"break<",
            forall a. Outputable a => a -> SDoc
ppr ArityInfo
ix,
            forall doc. IsLine doc => String -> doc
text String
">",
            forall doc. IsLine doc => doc -> doc
parens (forall doc. IsLine doc => [doc] -> doc
hcat (forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate forall doc. IsLine doc => doc
comma (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> SDoc
ppr [XTickishId pass]
vars)))]
  ppr (ProfNote { profNoteCC :: forall (pass :: TickishPass). GenTickish pass -> CostCentre
profNoteCC = CostCentre
cc,
                  profNoteCount :: forall (pass :: TickishPass). GenTickish pass -> Bool
profNoteCount = Bool
tick,
                  profNoteScope :: forall (pass :: TickishPass). GenTickish pass -> Bool
profNoteScope = Bool
scope }) =
      case (Bool
tick,Bool
scope) of
         (Bool
True,Bool
True)  -> forall doc. IsLine doc => [doc] -> doc
hcat [forall doc. IsLine doc => String -> doc
text String
"scctick<", forall a. Outputable a => a -> SDoc
ppr CostCentre
cc, forall doc. IsLine doc => Char -> doc
char Char
'>']
         (Bool
True,Bool
False) -> forall doc. IsLine doc => [doc] -> doc
hcat [forall doc. IsLine doc => String -> doc
text String
"tick<",    forall a. Outputable a => a -> SDoc
ppr CostCentre
cc, forall doc. IsLine doc => Char -> doc
char Char
'>']
         (Bool, Bool)
_            -> forall doc. IsLine doc => [doc] -> doc
hcat [forall doc. IsLine doc => String -> doc
text String
"scc<",     forall a. Outputable a => a -> SDoc
ppr CostCentre
cc, forall doc. IsLine doc => Char -> doc
char Char
'>']
  ppr (SourceNote RealSrcSpan
span String
_) =
      forall doc. IsLine doc => [doc] -> doc
hcat [ forall doc. IsLine doc => String -> doc
text String
"src<", Bool -> RealSrcSpan -> SDoc
pprUserRealSpan Bool
True RealSrcSpan
span, forall doc. IsLine doc => Char -> doc
char Char
'>']