{-# LANGUAGE PatternSynonyms #-}

-- | Pretty-printing types and coercions.
module GHC.Core.TyCo.Ppr
  (
        -- * Precedence
        PprPrec(..), topPrec, sigPrec, opPrec, funPrec, appPrec, maybeParen,

        -- * Pretty-printing types
        pprType, pprParendType, pprTidiedType, pprPrecType, pprPrecTypeX,
        pprTypeApp, pprTCvBndr, pprTCvBndrs,
        pprSigmaType,
        pprTheta, pprParendTheta, pprForAll, pprUserForAll,
        pprTyVar, pprTyVars,
        pprThetaArrowTy, pprClassPred,
        pprKind, pprParendKind, pprTyLit,
        pprDataCons, pprWithExplicitKindsWhen,
        pprWithTYPE, pprSourceTyCon,


        -- * Pretty-printing coercions
        pprCo, pprParendCo,

        debugPprType,
  ) where

import GHC.Prelude

import {-# SOURCE #-} GHC.CoreToIface
   ( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndrs
   , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercionX )

import {-# SOURCE #-} GHC.Core.DataCon
   ( dataConFullSig , dataConUserTyVarBinders, DataCon )

import GHC.Core.Type ( pickyIsLiftedTypeKind, pattern OneTy, pattern ManyTy,
                       splitForAllReqTyBinders, splitForAllInvisTyBinders )

import GHC.Core.TyCon
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.Tidy
import GHC.Core.TyCo.FVs
import GHC.Core.Class
import GHC.Types.Var
import GHC.Core.Multiplicity( pprArrowWithMultiplicity )
import GHC.Iface.Type

import GHC.Types.Var.Set
import GHC.Types.Var.Env

import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Types.Basic ( PprPrec(..), topPrec, sigPrec, opPrec
                       , funPrec, appPrec, maybeParen )

{-
%************************************************************************
%*                                                                      *
                   Pretty-printing types

       Defined very early because of debug printing in assertions
%*                                                                      *
%************************************************************************

@pprType@ is the standard @Type@ printer; the overloaded @ppr@ function is
defined to use this.  @pprParendType@ is the same, except it puts
parens around the type, except for the atomic cases.  @pprParendType@
works just by setting the initial context precedence very high.

Note that any function which pretty-prints a @Type@ first converts the @Type@
to an @IfaceType@. See Note [Pretty printing via Iface syntax] in GHC.Types.TyThing.Ppr.

See Note [Precedence in types] in GHC.Types.Basic.
-}

pprType, pprParendType, pprTidiedType :: Type -> SDoc
pprType :: Type -> SDoc
pprType       = PprPrec -> Type -> SDoc
pprPrecType PprPrec
topPrec
pprParendType :: Type -> SDoc
pprParendType = PprPrec -> Type -> SDoc
pprPrecType PprPrec
appPrec

-- already pre-tidied
pprTidiedType :: Type -> SDoc
pprTidiedType = IfaceType -> SDoc
pprIfaceType (IfaceType -> SDoc) -> (Type -> IfaceType) -> Type -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VarSet -> Type -> IfaceType
toIfaceTypeX VarSet
emptyVarSet

pprPrecType :: PprPrec -> Type -> SDoc
pprPrecType :: PprPrec -> Type -> SDoc
pprPrecType = TidyEnv -> PprPrec -> Type -> SDoc
pprPrecTypeX TidyEnv
emptyTidyEnv

pprPrecTypeX :: TidyEnv -> PprPrec -> Type -> SDoc
pprPrecTypeX :: TidyEnv -> PprPrec -> Type -> SDoc
pprPrecTypeX TidyEnv
env PprPrec
prec Type
ty
  = (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
sty ->
    (Bool -> SDoc) -> SDoc
forall doc. IsOutput doc => (Bool -> doc) -> doc
getPprDebug ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
debug ->
    if Bool
debug                    -- Use debugPprType when in
    then PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
prec Type
ty   -- when in debug-style
    else PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
prec (TidyEnv -> Type -> PprStyle -> IfaceType
tidyToIfaceTypeStyX TidyEnv
env Type
ty PprStyle
sty)
    -- NB: debug-style is used for -dppr-debug
    --     dump-style  is used for -ddump-tc-trace etc

pprTyLit :: TyLit -> SDoc
pprTyLit :: TyLit -> SDoc
pprTyLit = IfaceTyLit -> SDoc
pprIfaceTyLit (IfaceTyLit -> SDoc) -> (TyLit -> IfaceTyLit) -> TyLit -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyLit -> IfaceTyLit
toIfaceTyLit

pprKind, pprParendKind :: Kind -> SDoc
pprKind :: Type -> SDoc
pprKind       = Type -> SDoc
pprType
pprParendKind :: Type -> SDoc
pprParendKind = Type -> SDoc
pprParendType

tidyToIfaceTypeStyX :: TidyEnv -> Type -> PprStyle -> IfaceType
tidyToIfaceTypeStyX :: TidyEnv -> Type -> PprStyle -> IfaceType
tidyToIfaceTypeStyX TidyEnv
env Type
ty PprStyle
sty
  | PprStyle -> Bool
userStyle PprStyle
sty = TidyEnv -> Type -> IfaceType
tidyToIfaceTypeX TidyEnv
env Type
ty
  | Bool
otherwise     = VarSet -> Type -> IfaceType
toIfaceTypeX (Type -> VarSet
tyCoVarsOfType Type
ty) Type
ty
     -- in latter case, don't tidy, as we'll be printing uniques.

tidyToIfaceType :: Type -> IfaceType
tidyToIfaceType :: Type -> IfaceType
tidyToIfaceType = TidyEnv -> Type -> IfaceType
tidyToIfaceTypeX TidyEnv
emptyTidyEnv

tidyToIfaceTypeX :: TidyEnv -> Type -> IfaceType
-- It's vital to tidy before converting to an IfaceType
-- or nested binders will become indistinguishable!
--
-- Also for the free type variables, tell toIfaceTypeX to
-- leave them as IfaceFreeTyVar.  This is super-important
-- for debug printing.
tidyToIfaceTypeX :: TidyEnv -> Type -> IfaceType
tidyToIfaceTypeX TidyEnv
env Type
ty = VarSet -> Type -> IfaceType
toIfaceTypeX ([Var] -> VarSet
mkVarSet [Var]
free_tcvs) (TidyEnv -> Type -> Type
tidyType TidyEnv
env' Type
ty)
  where
    env' :: TidyEnv
env'      = TidyEnv -> [Var] -> TidyEnv
tidyFreeTyCoVars TidyEnv
env [Var]
free_tcvs
    free_tcvs :: [Var]
free_tcvs = Type -> [Var]
tyCoVarsOfTypeWellScoped Type
ty

------------
pprCo, pprParendCo :: Coercion -> SDoc
pprCo :: KindCoercion -> SDoc
pprCo       KindCoercion
co = (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \ PprStyle
sty -> IfaceCoercion -> SDoc
pprIfaceCoercion (KindCoercion -> PprStyle -> IfaceCoercion
tidyToIfaceCoSty KindCoercion
co PprStyle
sty)
pprParendCo :: KindCoercion -> SDoc
pprParendCo KindCoercion
co = (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \ PprStyle
sty -> IfaceCoercion -> SDoc
pprParendIfaceCoercion (KindCoercion -> PprStyle -> IfaceCoercion
tidyToIfaceCoSty KindCoercion
co PprStyle
sty)

tidyToIfaceCoSty :: Coercion -> PprStyle -> IfaceCoercion
tidyToIfaceCoSty :: KindCoercion -> PprStyle -> IfaceCoercion
tidyToIfaceCoSty KindCoercion
co PprStyle
sty
  | PprStyle -> Bool
userStyle PprStyle
sty = KindCoercion -> IfaceCoercion
tidyToIfaceCo KindCoercion
co
  | Bool
otherwise     = VarSet -> KindCoercion -> IfaceCoercion
toIfaceCoercionX (KindCoercion -> VarSet
tyCoVarsOfCo KindCoercion
co) KindCoercion
co
     -- in latter case, don't tidy, as we'll be printing uniques.

tidyToIfaceCo :: Coercion -> IfaceCoercion
-- It's vital to tidy before converting to an IfaceType
-- or nested binders will become indistinguishable!
--
-- Also for the free type variables, tell toIfaceCoercionX to
-- leave them as IfaceFreeCoVar.  This is super-important
-- for debug printing.
tidyToIfaceCo :: KindCoercion -> IfaceCoercion
tidyToIfaceCo KindCoercion
co = VarSet -> KindCoercion -> IfaceCoercion
toIfaceCoercionX ([Var] -> VarSet
mkVarSet [Var]
free_tcvs) (TidyEnv -> KindCoercion -> KindCoercion
tidyCo TidyEnv
env KindCoercion
co)
  where
    env :: TidyEnv
env       = TidyEnv -> [Var] -> TidyEnv
tidyFreeTyCoVars TidyEnv
emptyTidyEnv [Var]
free_tcvs
    free_tcvs :: [Var]
free_tcvs = [Var] -> [Var]
scopedSort ([Var] -> [Var]) -> [Var] -> [Var]
forall a b. (a -> b) -> a -> b
$ KindCoercion -> [Var]
tyCoVarsOfCoList KindCoercion
co
------------
pprClassPred :: Class -> [Type] -> SDoc
pprClassPred :: Class -> [Type] -> SDoc
pprClassPred Class
clas [Type]
tys = TyCon -> [Type] -> SDoc
pprTypeApp (Class -> TyCon
classTyCon Class
clas) [Type]
tys

------------
pprTheta :: ThetaType -> SDoc
pprTheta :: [Type] -> SDoc
pprTheta = PprPrec -> [IfaceType] -> SDoc
pprIfaceContext PprPrec
topPrec ([IfaceType] -> SDoc) -> ([Type] -> [IfaceType]) -> [Type] -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Type -> IfaceType) -> [Type] -> [IfaceType]
forall a b. (a -> b) -> [a] -> [b]
map Type -> IfaceType
tidyToIfaceType

pprParendTheta :: ThetaType -> SDoc
pprParendTheta :: [Type] -> SDoc
pprParendTheta = PprPrec -> [IfaceType] -> SDoc
pprIfaceContext PprPrec
appPrec ([IfaceType] -> SDoc) -> ([Type] -> [IfaceType]) -> [Type] -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Type -> IfaceType) -> [Type] -> [IfaceType]
forall a b. (a -> b) -> [a] -> [b]
map Type -> IfaceType
tidyToIfaceType

pprThetaArrowTy :: ThetaType -> SDoc
pprThetaArrowTy :: [Type] -> SDoc
pprThetaArrowTy = [IfaceType] -> SDoc
pprIfaceContextArr ([IfaceType] -> SDoc) -> ([Type] -> [IfaceType]) -> [Type] -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Type -> IfaceType) -> [Type] -> [IfaceType]
forall a b. (a -> b) -> [a] -> [b]
map Type -> IfaceType
tidyToIfaceType

------------------
pprSigmaType :: Type -> SDoc
pprSigmaType :: Type -> SDoc
pprSigmaType = ShowForAllFlag -> IfaceType -> SDoc
pprIfaceSigmaType ShowForAllFlag
ShowForAllWhen (IfaceType -> SDoc) -> (Type -> IfaceType) -> Type -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> IfaceType
tidyToIfaceType

pprForAll :: [ForAllTyBinder] -> SDoc
pprForAll :: [ForAllTyBinder] -> SDoc
pprForAll [ForAllTyBinder]
tvs = [IfaceForAllBndr] -> SDoc
pprIfaceForAll ([ForAllTyBinder] -> [IfaceForAllBndr]
forall flag. [VarBndr Var flag] -> [VarBndr IfaceBndr flag]
toIfaceForAllBndrs [ForAllTyBinder]
tvs)

-- | Print a user-level forall; see @Note [When to print foralls]@ in
-- "GHC.Iface.Type".
pprUserForAll :: [ForAllTyBinder] -> SDoc
pprUserForAll :: [ForAllTyBinder] -> SDoc
pprUserForAll = [IfaceForAllBndr] -> SDoc
pprUserIfaceForAll ([IfaceForAllBndr] -> SDoc)
-> ([ForAllTyBinder] -> [IfaceForAllBndr])
-> [ForAllTyBinder]
-> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ForAllTyBinder] -> [IfaceForAllBndr]
forall flag. [VarBndr Var flag] -> [VarBndr IfaceBndr flag]
toIfaceForAllBndrs

pprTCvBndrs :: [ForAllTyBinder] -> SDoc
pprTCvBndrs :: [ForAllTyBinder] -> SDoc
pprTCvBndrs [ForAllTyBinder]
tvs = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((ForAllTyBinder -> SDoc) -> [ForAllTyBinder] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ForAllTyBinder -> SDoc
pprTCvBndr [ForAllTyBinder]
tvs)

pprTCvBndr :: ForAllTyBinder -> SDoc
pprTCvBndr :: ForAllTyBinder -> SDoc
pprTCvBndr = Var -> SDoc
pprTyVar (Var -> SDoc) -> (ForAllTyBinder -> Var) -> ForAllTyBinder -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForAllTyBinder -> Var
forall tv argf. VarBndr tv argf -> tv
binderVar

pprTyVars :: [TyVar] -> SDoc
pprTyVars :: [Var] -> SDoc
pprTyVars [Var]
tvs = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((Var -> SDoc) -> [Var] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Var -> SDoc
pprTyVar [Var]
tvs)

pprTyVar :: TyVar -> SDoc
-- Print a type variable binder with its kind (but not if *)
-- Here we do not go via IfaceType, because the duplication with
-- pprIfaceTvBndr is minimal, and the loss of uniques etc in
-- debug printing is disastrous
pprTyVar :: Var -> SDoc
pprTyVar Var
tv
  | Type -> Bool
pickyIsLiftedTypeKind Type
kind = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv  -- See Note [Suppressing * kinds]
  | Bool
otherwise                  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
kind)
  where
    kind :: Type
kind = Var -> Type
tyVarKind Var
tv

{- Note [Suppressing * kinds]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generally we want to print
      forall a. a->a
not   forall (a::*). a->a
or    forall (a::Type). a->a
That is, for brevity we suppress a kind ascription of '*' (or Type).

But what if the kind is (Const Type x)?
   type Const p q = p

Then (Const Type x) is just a long way of saying Type.  But it may be
jolly confusing to suppress the 'x'.  Suppose we have (polykinds/T18451a)
   foo :: forall a b (c :: Const Type b). Proxy '[a, c]

Then this error message
    • These kind and type variables: a b (c :: Const Type b)
      are out of dependency order. Perhaps try this ordering:
        (b :: k) (a :: Const (*) b) (c :: Const (*) b)
would be much less helpful if we suppressed the kind ascription on 'a'.

Hence the use of pickyIsLiftedTypeKind.
-}

-----------------
debugPprType :: Type -> SDoc
-- ^ debugPprType is a simple pretty printer that prints a type
-- without going through IfaceType.  It does not format as prettily
-- as the normal route, but it's much more direct, and that can
-- be useful for debugging.  E.g. with -dppr-debug it prints the
-- kind on type-variable /occurrences/ which the normal route
-- fundamentally cannot do.
debugPprType :: Type -> SDoc
debugPprType Type
ty = PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
topPrec Type
ty

debug_ppr_ty :: PprPrec -> Type -> SDoc
debug_ppr_ty :: PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
_ (LitTy TyLit
l)
  = TyLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyLit
l

debug_ppr_ty PprPrec
_ (TyVarTy Var
tv)
  = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
tv  -- With -dppr-debug we get (tv :: kind)

debug_ppr_ty PprPrec
prec (FunTy { ft_af :: Type -> FunTyFlag
ft_af = FunTyFlag
af, ft_mult :: Type -> Type
ft_mult = Type
mult, ft_arg :: Type -> Type
ft_arg = Type
arg, ft_res :: Type -> Type
ft_res = Type
res })
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
funPrec Type
arg, SDoc
arr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
prec Type
res]
  where
    arr :: SDoc
arr = FunTyFlag -> Either Bool SDoc -> SDoc
pprArrowWithMultiplicity FunTyFlag
af (Either Bool SDoc -> SDoc) -> Either Bool SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
          case Type
mult of
            Type
OneTy  -> Bool -> Either Bool SDoc
forall a b. a -> Either a b
Left Bool
True
            Type
ManyTy -> Bool -> Either Bool SDoc
forall a b. a -> Either a b
Left Bool
False
            Type
_      -> SDoc -> Either Bool SDoc
forall a b. b -> Either a b
Right (PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
appPrec Type
mult)

debug_ppr_ty PprPrec
prec (TyConApp TyCon
tc [Type]
tys)
  | [Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
tys  = TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc
  | Bool
otherwise = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
appPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
                SDoc -> Int -> SDoc -> SDoc
hang (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc) Int
2 ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((Type -> SDoc) -> [Type] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
appPrec) [Type]
tys))

debug_ppr_ty PprPrec
_ (AppTy Type
t1 Type
t2)
  = SDoc -> Int -> SDoc -> SDoc
hang (PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
appPrec Type
t1)  -- Print parens so we see ((a b) c)
       Int
2 (PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
appPrec Type
t2)  -- so that we can distinguish
                                    -- TyConApp from AppTy

debug_ppr_ty PprPrec
prec (CastTy Type
ty KindCoercion
co)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
topPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    SDoc -> Int -> SDoc -> SDoc
hang (PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
topPrec Type
ty)
       Int
2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"|>" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> KindCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr KindCoercion
co)

debug_ppr_ty PprPrec
_ (CoercionTy KindCoercion
co)
  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"CO" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> KindCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr KindCoercion
co)

-- Invisible forall:  forall {k} (a :: k). t
debug_ppr_ty PprPrec
prec Type
t
  | ([InvisTyBinder]
bndrs, Type
body) <- Type -> ([InvisTyBinder], Type)
splitForAllInvisTyBinders Type
t
  , Bool -> Bool
not ([InvisTyBinder] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InvisTyBinder]
bndrs)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"forall" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
fsep ((InvisTyBinder -> SDoc) -> [InvisTyBinder] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map InvisTyBinder -> SDoc
forall {a}. Outputable a => VarBndr a Specificity -> SDoc
ppr_bndr [InvisTyBinder]
bndrs) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
dot,
          Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
body ]
  where
    -- (ppr tv) will print the binder kind-annotated
    -- when in debug-style
    ppr_bndr :: VarBndr a Specificity -> SDoc
ppr_bndr (Bndr a
tv Specificity
InferredSpec)  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
tv)
    ppr_bndr (Bndr a
tv Specificity
SpecifiedSpec) = a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
tv

-- Visible forall:  forall x y -> t
debug_ppr_ty PprPrec
prec Type
t
  | ([ReqTyBinder]
bndrs, Type
body) <- Type -> ([ReqTyBinder], Type)
splitForAllReqTyBinders Type
t
  , Bool -> Bool
not ([ReqTyBinder] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ReqTyBinder]
bndrs)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"forall" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
fsep ((ReqTyBinder -> SDoc) -> [ReqTyBinder] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ReqTyBinder -> SDoc
forall {a}. Outputable a => VarBndr a () -> SDoc
ppr_bndr [ReqTyBinder]
bndrs) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow,
          Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
body ]
  where
    -- (ppr tv) will print the binder kind-annotated
    -- when in debug-style
    ppr_bndr :: VarBndr a () -> SDoc
ppr_bndr (Bndr a
tv ()) = a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
tv

-- Impossible case: neither visible nor invisible forall.
debug_ppr_ty PprPrec
_ ForAllTy{}
  = String -> SDoc
forall a. HasCallStack => String -> a
panic String
"debug_ppr_ty: neither splitForAllInvisTyBinders nor splitForAllReqTyBinders returned any binders"

{-
Note [Infix type variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
With TypeOperators you can say

   f :: (a ~> b) -> b

and the (~>) is considered a type variable.  However, the type
pretty-printer in this module will just see (a ~> b) as

   App (App (TyVarTy "~>") (TyVarTy "a")) (TyVarTy "b")

So it'll print the type in prefix form.  To avoid confusion we must
remember to parenthesise the operator, thus

   (~>) a b -> b

See #2766.
-}

pprDataCons :: TyCon -> SDoc
pprDataCons :: TyCon -> SDoc
pprDataCons = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sepWithVBars ([SDoc] -> SDoc) -> (TyCon -> [SDoc]) -> TyCon -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DataCon -> SDoc) -> [DataCon] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DataCon -> SDoc
pprDataConWithArgs ([DataCon] -> [SDoc]) -> (TyCon -> [DataCon]) -> TyCon -> [SDoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> [DataCon]
tyConDataCons
  where
    sepWithVBars :: [doc] -> doc
sepWithVBars [] = doc
forall doc. IsOutput doc => doc
empty
    sepWithVBars [doc]
docs = [doc] -> doc
forall doc. IsLine doc => [doc] -> doc
sep (doc -> [doc] -> [doc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate (doc
forall doc. IsLine doc => doc
space doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
vbar) [doc]
docs)

pprDataConWithArgs :: DataCon -> SDoc
pprDataConWithArgs :: DataCon -> SDoc
pprDataConWithArgs DataCon
dc = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [SDoc
forAllDoc, SDoc
thetaDoc, DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
argsDoc]
  where
    ([Var]
_univ_tvs, [Var]
_ex_tvs, [EqSpec]
_eq_spec, [Type]
theta, [Scaled Type]
arg_tys, Type
_res_ty) = DataCon -> ([Var], [Var], [EqSpec], [Type], [Scaled Type], Type)
dataConFullSig DataCon
dc
    user_bndrs :: [ForAllTyBinder]
user_bndrs = [InvisTyBinder] -> [ForAllTyBinder]
forall a. [VarBndr a Specificity] -> [VarBndr a ForAllTyFlag]
tyVarSpecToBinders ([InvisTyBinder] -> [ForAllTyBinder])
-> [InvisTyBinder] -> [ForAllTyBinder]
forall a b. (a -> b) -> a -> b
$ DataCon -> [InvisTyBinder]
dataConUserTyVarBinders DataCon
dc
    forAllDoc :: SDoc
forAllDoc  = [ForAllTyBinder] -> SDoc
pprUserForAll [ForAllTyBinder]
user_bndrs
    thetaDoc :: SDoc
thetaDoc   = [Type] -> SDoc
pprThetaArrowTy [Type]
theta
    argsDoc :: SDoc
argsDoc    = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep ((Type -> SDoc) -> [Type] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> SDoc
pprParendType ((Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing [Scaled Type]
arg_tys))


pprTypeApp :: TyCon -> [Type] -> SDoc
pprTypeApp :: TyCon -> [Type] -> SDoc
pprTypeApp TyCon
tc [Type]
tys
  = PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprIfaceTypeApp PprPrec
topPrec (TyCon -> IfaceTyCon
toIfaceTyCon TyCon
tc)
                            (TyCon -> [Type] -> IfaceAppArgs
toIfaceTcArgs TyCon
tc [Type]
tys)
    -- TODO: toIfaceTcArgs seems rather wasteful here

------------------
-- | Display all kind information (with @-fprint-explicit-kinds@) when the
-- provided 'Bool' argument is 'True'.
-- See @Note [Kind arguments in error messages]@ in "GHC.Tc.Errors".
pprWithExplicitKindsWhen :: Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen :: Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen Bool
b
  = (SDocContext -> SDocContext) -> SDoc -> SDoc
updSDocContext ((SDocContext -> SDocContext) -> SDoc -> SDoc)
-> (SDocContext -> SDocContext) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ \SDocContext
ctx ->
      if Bool
b then SDocContext
ctx { sdocPrintExplicitKinds = True }
           else SDocContext
ctx

-- | This variant preserves any use of TYPE in a type, effectively
-- locally setting -fprint-explicit-runtime-reps.
pprWithTYPE :: Type -> SDoc
pprWithTYPE :: Type -> SDoc
pprWithTYPE Type
ty = (SDocContext -> SDocContext) -> SDoc -> SDoc
updSDocContext (\SDocContext
ctx -> SDocContext
ctx { sdocPrintExplicitRuntimeReps = True }) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
                 Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty

-- | Pretty prints a 'TyCon', using the family instance in case of a
-- representation tycon.  For example:
--
-- > data T [a] = ...
--
-- In that case we want to print @T [a]@, where @T@ is the family 'TyCon'
pprSourceTyCon :: TyCon -> SDoc
pprSourceTyCon :: TyCon -> SDoc
pprSourceTyCon TyCon
tycon
  | Just (TyCon
fam_tc, [Type]
tys) <- TyCon -> Maybe (TyCon, [Type])
tyConFamInst_maybe TyCon
tycon
  = Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Type -> SDoc) -> Type -> SDoc
forall a b. (a -> b) -> a -> b
$ TyCon
fam_tc TyCon -> [Type] -> Type
`TyConApp` [Type]
tys        -- can't be FunTyCon
  | Bool
otherwise
  = TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tycon