{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1993-1998


This module defines interface types and binders
-}


{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE LambdaCase #-}
module GHC.Iface.Type (
        IfExtName,
        IfLclName(..), mkIfLclName, ifLclNameFS,

        IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..),
        IfaceAxiomRule(..),IfaceMCoercion(..),
        IfaceMult,
        IfaceTyCon(..),
        IfaceTyConInfo(..), mkIfaceTyConInfo,
        IfaceTyConSort(..),
        IfaceTyLit(..), IfaceAppArgs(..),
        IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr,
        IfaceTvBndr, IfaceIdBndr, IfaceTyConBinder,
        IfaceForAllSpecBndr,
        IfaceForAllBndr, ForAllTyFlag(..), FunTyFlag(..), ShowForAllFlag(..),
        ShowSub(..), ShowHowMuch(..), AltPpr(..),
        mkIfaceForAllTvBndr,
        mkIfaceTyConKind,
        ifaceForAllSpecToBndrs, ifaceForAllSpecToBndr,

        ifForAllBndrVar, ifForAllBndrName, ifaceBndrName,
        ifTyConBinderVar, ifTyConBinderName,

        -- Binary utilities
        putIfaceType, getIfaceType, ifaceTypeSharedByte,
        -- Equality testing
        isIfaceLiftedTypeKind,

        -- Conversion from IfaceAppArgs to IfaceTypes/ForAllTyFlags
        appArgsIfaceTypes, appArgsIfaceTypesForAllTyFlags,

        -- Printing
        SuppressBndrSig(..),
        UseBndrParens(..),
        PrintExplicitKinds(..),
        PrintArityInvisibles(..),
        pprIfaceType, pprParendIfaceType, pprPrecIfaceType,
        pprIfaceContext, pprIfaceContextArr,
        pprIfaceIdBndr, pprIfaceLamBndr, pprIfaceTvBndr, pprIfaceTyConBinders,
        pprIfaceBndrs, pprIfaceAppArgs, pprParendIfaceAppArgs,
        pprIfaceForAllPart, pprIfaceForAllPartMust, pprIfaceForAll,
        pprIfaceSigmaType, pprIfaceTyLit,
        pprIfaceCoercion, pprParendIfaceCoercion,
        splitIfaceSigmaTy, pprIfaceTypeApp, pprUserIfaceForAll,
        pprIfaceCoTcApp, pprTyTcApp, pprIfacePrefixApp,
        isIfaceRhoType,

        suppressIfaceInvisibles,
        visibleTypeVarOccurencies,
        stripIfaceInvisVars,
        stripInvisArgs,

        mkIfaceTySubst, substIfaceTyVar, substIfaceAppArgs, inDomIfaceTySubst,

        many_ty, pprTypeArrow
    ) where

import GHC.Prelude

import {-# SOURCE #-} GHC.Builtin.Types
                                 ( coercibleTyCon, heqTyCon
                                 , constraintKindTyConName
                                 , tupleTyConName
                                 , tupleDataConName
                                 , manyDataConTyCon
                                 , liftedRepTyCon, liftedDataConTyCon
                                 , sumTyCon )
import GHC.Core.Type ( isRuntimeRepTy, isMultiplicityTy, isLevityTy, funTyFlagTyCon )
import GHC.Core.TyCo.Rep( CoSel, UnivCoProvenance(..) )
import GHC.Core.TyCo.Compare( eqForAllVis )
import GHC.Core.TyCon hiding ( pprPromotionQuote )
import GHC.Core.Coercion.Axiom
import GHC.Types.Var
import GHC.Builtin.Names
import {-# SOURCE #-} GHC.Builtin.Types ( liftedTypeKindTyConName )
import GHC.Types.Name
import GHC.Types.Basic
import GHC.Utils.Binary
import GHC.Utils.Outputable
import GHC.Data.FastString
import GHC.Utils.Misc
import GHC.Utils.Panic
import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isMetaTyVar, isTyConableTyVar )

import Data.Maybe (isJust)
import Data.Proxy
import qualified Data.Semigroup as Semi
import Data.Word (Word8)
import Control.Arrow (first)
import Control.DeepSeq
import Control.Monad ((<$!>))
import Data.List (dropWhileEnd)
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Set as Set

{-
************************************************************************
*                                                                      *
                Local (nested) binders
*                                                                      *
************************************************************************
-}

-- | A local name in iface syntax
newtype IfLclName = IfLclName
  { IfLclName -> LexicalFastString
getIfLclName :: LexicalFastString
  } deriving (IfLclName -> IfLclName -> Bool
(IfLclName -> IfLclName -> Bool)
-> (IfLclName -> IfLclName -> Bool) -> Eq IfLclName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfLclName -> IfLclName -> Bool
== :: IfLclName -> IfLclName -> Bool
$c/= :: IfLclName -> IfLclName -> Bool
/= :: IfLclName -> IfLclName -> Bool
Eq, Eq IfLclName
Eq IfLclName =>
(IfLclName -> IfLclName -> Ordering)
-> (IfLclName -> IfLclName -> Bool)
-> (IfLclName -> IfLclName -> Bool)
-> (IfLclName -> IfLclName -> Bool)
-> (IfLclName -> IfLclName -> Bool)
-> (IfLclName -> IfLclName -> IfLclName)
-> (IfLclName -> IfLclName -> IfLclName)
-> Ord IfLclName
IfLclName -> IfLclName -> Bool
IfLclName -> IfLclName -> Ordering
IfLclName -> IfLclName -> IfLclName
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfLclName -> IfLclName -> Ordering
compare :: IfLclName -> IfLclName -> Ordering
$c< :: IfLclName -> IfLclName -> Bool
< :: IfLclName -> IfLclName -> Bool
$c<= :: IfLclName -> IfLclName -> Bool
<= :: IfLclName -> IfLclName -> Bool
$c> :: IfLclName -> IfLclName -> Bool
> :: IfLclName -> IfLclName -> Bool
$c>= :: IfLclName -> IfLclName -> Bool
>= :: IfLclName -> IfLclName -> Bool
$cmax :: IfLclName -> IfLclName -> IfLclName
max :: IfLclName -> IfLclName -> IfLclName
$cmin :: IfLclName -> IfLclName -> IfLclName
min :: IfLclName -> IfLclName -> IfLclName
Ord, Int -> IfLclName -> ShowS
[IfLclName] -> ShowS
IfLclName -> String
(Int -> IfLclName -> ShowS)
-> (IfLclName -> String)
-> ([IfLclName] -> ShowS)
-> Show IfLclName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IfLclName -> ShowS
showsPrec :: Int -> IfLclName -> ShowS
$cshow :: IfLclName -> String
show :: IfLclName -> String
$cshowList :: [IfLclName] -> ShowS
showList :: [IfLclName] -> ShowS
Show)

ifLclNameFS :: IfLclName -> FastString
ifLclNameFS :: IfLclName -> FastString
ifLclNameFS = LexicalFastString -> FastString
getLexicalFastString (LexicalFastString -> FastString)
-> (IfLclName -> LexicalFastString) -> IfLclName -> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IfLclName -> LexicalFastString
getIfLclName

mkIfLclName :: FastString -> IfLclName
mkIfLclName :: FastString -> IfLclName
mkIfLclName = LexicalFastString -> IfLclName
IfLclName (LexicalFastString -> IfLclName)
-> (FastString -> LexicalFastString) -> FastString -> IfLclName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FastString -> LexicalFastString
LexicalFastString

type IfExtName = Name   -- An External or WiredIn Name can appear in Iface syntax
                        -- (However Internal or System Names never should)

data IfaceBndr          -- Local (non-top-level) binders
  = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr
  | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr
  deriving (IfaceBndr -> IfaceBndr -> Bool
(IfaceBndr -> IfaceBndr -> Bool)
-> (IfaceBndr -> IfaceBndr -> Bool) -> Eq IfaceBndr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceBndr -> IfaceBndr -> Bool
== :: IfaceBndr -> IfaceBndr -> Bool
$c/= :: IfaceBndr -> IfaceBndr -> Bool
/= :: IfaceBndr -> IfaceBndr -> Bool
Eq, Eq IfaceBndr
Eq IfaceBndr =>
(IfaceBndr -> IfaceBndr -> Ordering)
-> (IfaceBndr -> IfaceBndr -> Bool)
-> (IfaceBndr -> IfaceBndr -> Bool)
-> (IfaceBndr -> IfaceBndr -> Bool)
-> (IfaceBndr -> IfaceBndr -> Bool)
-> (IfaceBndr -> IfaceBndr -> IfaceBndr)
-> (IfaceBndr -> IfaceBndr -> IfaceBndr)
-> Ord IfaceBndr
IfaceBndr -> IfaceBndr -> Bool
IfaceBndr -> IfaceBndr -> Ordering
IfaceBndr -> IfaceBndr -> IfaceBndr
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceBndr -> IfaceBndr -> Ordering
compare :: IfaceBndr -> IfaceBndr -> Ordering
$c< :: IfaceBndr -> IfaceBndr -> Bool
< :: IfaceBndr -> IfaceBndr -> Bool
$c<= :: IfaceBndr -> IfaceBndr -> Bool
<= :: IfaceBndr -> IfaceBndr -> Bool
$c> :: IfaceBndr -> IfaceBndr -> Bool
> :: IfaceBndr -> IfaceBndr -> Bool
$c>= :: IfaceBndr -> IfaceBndr -> Bool
>= :: IfaceBndr -> IfaceBndr -> Bool
$cmax :: IfaceBndr -> IfaceBndr -> IfaceBndr
max :: IfaceBndr -> IfaceBndr -> IfaceBndr
$cmin :: IfaceBndr -> IfaceBndr -> IfaceBndr
min :: IfaceBndr -> IfaceBndr -> IfaceBndr
Ord)


type IfaceIdBndr  = (IfaceType, IfLclName, IfaceType)
type IfaceTvBndr  = (IfLclName, IfaceKind)

ifaceTvBndrName :: IfaceTvBndr -> IfLclName
ifaceTvBndrName :: IfaceTvBndr -> IfLclName
ifaceTvBndrName (IfLclName
n,IfaceType
_) = IfLclName
n

ifaceIdBndrName :: IfaceIdBndr -> IfLclName
ifaceIdBndrName :: IfaceIdBndr -> IfLclName
ifaceIdBndrName (IfaceType
_,IfLclName
n,IfaceType
_) = IfLclName
n

ifaceBndrName :: IfaceBndr -> IfLclName
ifaceBndrName :: IfaceBndr -> IfLclName
ifaceBndrName (IfaceTvBndr IfaceTvBndr
bndr) = IfaceTvBndr -> IfLclName
ifaceTvBndrName IfaceTvBndr
bndr
ifaceBndrName (IfaceIdBndr IfaceIdBndr
bndr) = IfaceIdBndr -> IfLclName
ifaceIdBndrName IfaceIdBndr
bndr

ifaceBndrType :: IfaceBndr -> IfaceType
ifaceBndrType :: IfaceBndr -> IfaceType
ifaceBndrType (IfaceIdBndr (IfaceType
_, IfLclName
_, IfaceType
t)) = IfaceType
t
ifaceBndrType (IfaceTvBndr (IfLclName
_, IfaceType
t)) = IfaceType
t

type IfaceLamBndr = (IfaceBndr, IfaceOneShot)

data IfaceOneShot    -- See Note [Preserve OneShotInfo] in "GHC.Core.Tidy"
  = IfaceNoOneShot   -- and Note [oneShot magic] in "GHC.Types.Id.Make"
  | IfaceOneShot

instance Outputable IfaceOneShot where
  ppr :: IfaceOneShot -> SDoc
ppr IfaceOneShot
IfaceNoOneShot = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"NoOneShotInfo"
  ppr IfaceOneShot
IfaceOneShot = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"OneShot"

{-
%************************************************************************
%*                                                                      *
                IfaceType
%*                                                                      *
%************************************************************************
-}

-------------------------------
type IfaceKind     = IfaceType

-- | A kind of universal type, used for types and kinds.
--
-- Any time a 'Type' is pretty-printed, it is first converted to an 'IfaceType'
-- before being printed. See Note [Pretty printing via Iface syntax] in "GHC.Types.TyThing.Ppr"
data IfaceType
  = IfaceFreeTyVar TyVar                -- See Note [Free TyVars and CoVars in IfaceType]
  | IfaceTyVar     IfLclName            -- Type/coercion variable only, not tycon
  | IfaceLitTy     IfaceTyLit
  | IfaceAppTy     IfaceType IfaceAppArgs
                             -- See Note [Suppressing invisible arguments] for
                             -- an explanation of why the second field isn't
                             -- IfaceType, analogous to AppTy.
  | IfaceFunTy     FunTyFlag IfaceMult IfaceType IfaceType
  | IfaceForAllTy  IfaceForAllBndr IfaceType
  | IfaceTyConApp  IfaceTyCon IfaceAppArgs  -- Not necessarily saturated
                                            -- Includes newtypes, synonyms, tuples
  | IfaceCastTy     IfaceType IfaceCoercion
  | IfaceCoercionTy IfaceCoercion

  | IfaceTupleTy                  -- Saturated tuples (unsaturated ones use IfaceTyConApp)
       TupleSort                  -- What sort of tuple?
       PromotionFlag                 -- A bit like IfaceTyCon
       IfaceAppArgs               -- arity = length args
          -- For promoted data cons, the kind args are omitted
          -- Why have this? Only for efficiency: IfaceTupleTy can omit the
          -- type arguments, as they can be recreated when deserializing.
          -- In an experiment, removing IfaceTupleTy resulted in a 0.75% regression
          -- in interface file size (in GHC's boot libraries).
          -- See !3987.
  deriving (IfaceType -> IfaceType -> Bool
(IfaceType -> IfaceType -> Bool)
-> (IfaceType -> IfaceType -> Bool) -> Eq IfaceType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceType -> IfaceType -> Bool
== :: IfaceType -> IfaceType -> Bool
$c/= :: IfaceType -> IfaceType -> Bool
/= :: IfaceType -> IfaceType -> Bool
Eq, Eq IfaceType
Eq IfaceType =>
(IfaceType -> IfaceType -> Ordering)
-> (IfaceType -> IfaceType -> Bool)
-> (IfaceType -> IfaceType -> Bool)
-> (IfaceType -> IfaceType -> Bool)
-> (IfaceType -> IfaceType -> Bool)
-> (IfaceType -> IfaceType -> IfaceType)
-> (IfaceType -> IfaceType -> IfaceType)
-> Ord IfaceType
IfaceType -> IfaceType -> Bool
IfaceType -> IfaceType -> Ordering
IfaceType -> IfaceType -> IfaceType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceType -> IfaceType -> Ordering
compare :: IfaceType -> IfaceType -> Ordering
$c< :: IfaceType -> IfaceType -> Bool
< :: IfaceType -> IfaceType -> Bool
$c<= :: IfaceType -> IfaceType -> Bool
<= :: IfaceType -> IfaceType -> Bool
$c> :: IfaceType -> IfaceType -> Bool
> :: IfaceType -> IfaceType -> Bool
$c>= :: IfaceType -> IfaceType -> Bool
>= :: IfaceType -> IfaceType -> Bool
$cmax :: IfaceType -> IfaceType -> IfaceType
max :: IfaceType -> IfaceType -> IfaceType
$cmin :: IfaceType -> IfaceType -> IfaceType
min :: IfaceType -> IfaceType -> IfaceType
Ord)
  -- See Note [Ord instance of IfaceType]

{-
Note [Ord instance of IfaceType]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We need an 'Ord' instance to have a 'Map' keyed by 'IfaceType'. This 'Map' is
required for implementing the deduplication table during interface file
serialisation.
See Note [Deduplication during iface binary serialisation] for the implementation details.

We experimented with a 'TrieMap' based implementation, but it seems to be
slower than using a straight-forward 'Map IfaceType'.
The experiments loaded the full agda library into a ghci session with the
following scenarios:

* normal: a plain ghci session.
* cold: a ghci session that uses '-fwrite-if-simplified-core -fforce-recomp',
  forcing a cold-cache.
* warm: a subsequent ghci session that uses a warm cache for
  '-fwrite-if-simplified-core', e.g. nothing needs to be recompiled.

The implementation was up to 5% slower in some execution runs. However, on
'lib:Cabal', the performance difference between 'Map IfaceType' and
'TrieMap IfaceType' was negligible.

We share our implementation of the 'TrieMap' in the ticket #24816, so that
further performance analysis and improvements don't need to start from scratch.
-}

type IfaceMult = IfaceType

type IfacePredType = IfaceType
type IfaceContext = [IfacePredType]

data IfaceTyLit
  = IfaceNumTyLit Integer
  | IfaceStrTyLit LexicalFastString
  | IfaceCharTyLit Char
  deriving (IfaceTyLit -> IfaceTyLit -> Bool
(IfaceTyLit -> IfaceTyLit -> Bool)
-> (IfaceTyLit -> IfaceTyLit -> Bool) -> Eq IfaceTyLit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceTyLit -> IfaceTyLit -> Bool
== :: IfaceTyLit -> IfaceTyLit -> Bool
$c/= :: IfaceTyLit -> IfaceTyLit -> Bool
/= :: IfaceTyLit -> IfaceTyLit -> Bool
Eq, Eq IfaceTyLit
Eq IfaceTyLit =>
(IfaceTyLit -> IfaceTyLit -> Ordering)
-> (IfaceTyLit -> IfaceTyLit -> Bool)
-> (IfaceTyLit -> IfaceTyLit -> Bool)
-> (IfaceTyLit -> IfaceTyLit -> Bool)
-> (IfaceTyLit -> IfaceTyLit -> Bool)
-> (IfaceTyLit -> IfaceTyLit -> IfaceTyLit)
-> (IfaceTyLit -> IfaceTyLit -> IfaceTyLit)
-> Ord IfaceTyLit
IfaceTyLit -> IfaceTyLit -> Bool
IfaceTyLit -> IfaceTyLit -> Ordering
IfaceTyLit -> IfaceTyLit -> IfaceTyLit
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceTyLit -> IfaceTyLit -> Ordering
compare :: IfaceTyLit -> IfaceTyLit -> Ordering
$c< :: IfaceTyLit -> IfaceTyLit -> Bool
< :: IfaceTyLit -> IfaceTyLit -> Bool
$c<= :: IfaceTyLit -> IfaceTyLit -> Bool
<= :: IfaceTyLit -> IfaceTyLit -> Bool
$c> :: IfaceTyLit -> IfaceTyLit -> Bool
> :: IfaceTyLit -> IfaceTyLit -> Bool
$c>= :: IfaceTyLit -> IfaceTyLit -> Bool
>= :: IfaceTyLit -> IfaceTyLit -> Bool
$cmax :: IfaceTyLit -> IfaceTyLit -> IfaceTyLit
max :: IfaceTyLit -> IfaceTyLit -> IfaceTyLit
$cmin :: IfaceTyLit -> IfaceTyLit -> IfaceTyLit
min :: IfaceTyLit -> IfaceTyLit -> IfaceTyLit
Ord)

type IfaceTyConBinder    = VarBndr IfaceBndr TyConBndrVis
type IfaceForAllBndr     = VarBndr IfaceBndr ForAllTyFlag
type IfaceForAllSpecBndr = VarBndr IfaceBndr Specificity

-- | Make an 'IfaceForAllBndr' from an 'IfaceTvBndr'.
mkIfaceForAllTvBndr :: ForAllTyFlag -> IfaceTvBndr -> IfaceForAllBndr
mkIfaceForAllTvBndr :: ForAllTyFlag -> IfaceTvBndr -> IfaceForAllBndr
mkIfaceForAllTvBndr ForAllTyFlag
vis IfaceTvBndr
var = IfaceBndr -> ForAllTyFlag -> IfaceForAllBndr
forall var argf. var -> argf -> VarBndr var argf
Bndr (IfaceTvBndr -> IfaceBndr
IfaceTvBndr IfaceTvBndr
var) ForAllTyFlag
vis

-- | Build the 'tyConKind' from the binders and the result kind.
-- Keep in sync with 'mkTyConKind' in "GHC.Core.TyCon".
mkIfaceTyConKind :: [IfaceTyConBinder] -> IfaceKind -> IfaceKind
mkIfaceTyConKind :: [IfaceTyConBinder] -> IfaceType -> IfaceType
mkIfaceTyConKind [IfaceTyConBinder]
bndrs IfaceType
res_kind = (IfaceTyConBinder -> IfaceType -> IfaceType)
-> IfaceType -> [IfaceTyConBinder] -> IfaceType
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr IfaceTyConBinder -> IfaceType -> IfaceType
mk IfaceType
res_kind [IfaceTyConBinder]
bndrs
  where
    mk :: IfaceTyConBinder -> IfaceKind -> IfaceKind
    mk :: IfaceTyConBinder -> IfaceType -> IfaceType
mk (Bndr IfaceBndr
tv TyConBndrVis
AnonTCB)        IfaceType
k = FunTyFlag -> IfaceType -> IfaceType -> IfaceType -> IfaceType
IfaceFunTy FunTyFlag
FTF_T_T IfaceType
many_ty (IfaceBndr -> IfaceType
ifaceBndrType IfaceBndr
tv) IfaceType
k
    mk (Bndr IfaceBndr
tv (NamedTCB ForAllTyFlag
vis)) IfaceType
k = IfaceForAllBndr -> IfaceType -> IfaceType
IfaceForAllTy (IfaceBndr -> ForAllTyFlag -> IfaceForAllBndr
forall var argf. var -> argf -> VarBndr var argf
Bndr IfaceBndr
tv ForAllTyFlag
vis) IfaceType
k

ifaceForAllSpecToBndrs :: [IfaceForAllSpecBndr] -> [IfaceForAllBndr]
ifaceForAllSpecToBndrs :: [IfaceForAllSpecBndr] -> [IfaceForAllBndr]
ifaceForAllSpecToBndrs = (IfaceForAllSpecBndr -> IfaceForAllBndr)
-> [IfaceForAllSpecBndr] -> [IfaceForAllBndr]
forall a b. (a -> b) -> [a] -> [b]
map IfaceForAllSpecBndr -> IfaceForAllBndr
ifaceForAllSpecToBndr

ifaceForAllSpecToBndr :: IfaceForAllSpecBndr -> IfaceForAllBndr
ifaceForAllSpecToBndr :: IfaceForAllSpecBndr -> IfaceForAllBndr
ifaceForAllSpecToBndr (Bndr IfaceBndr
tv Specificity
spec) = IfaceBndr -> ForAllTyFlag -> IfaceForAllBndr
forall var argf. var -> argf -> VarBndr var argf
Bndr IfaceBndr
tv (Specificity -> ForAllTyFlag
Invisible Specificity
spec)

-- | Stores the arguments in a type application as a list.
-- See @Note [Suppressing invisible arguments]@.
data IfaceAppArgs
  = IA_Nil
  | IA_Arg IfaceType    -- The type argument

           ForAllTyFlag      -- The argument's visibility. We store this here so
                        -- that we can:
                        --
                        -- 1. Avoid pretty-printing invisible (i.e., specified
                        --    or inferred) arguments when
                        --    -fprint-explicit-kinds isn't enabled, or
                        -- 2. When -fprint-explicit-kinds *is*, enabled, print
                        --    specified arguments in @(...) and inferred
                        --    arguments in @{...}.

           IfaceAppArgs -- The rest of the arguments
  deriving (IfaceAppArgs -> IfaceAppArgs -> Bool
(IfaceAppArgs -> IfaceAppArgs -> Bool)
-> (IfaceAppArgs -> IfaceAppArgs -> Bool) -> Eq IfaceAppArgs
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceAppArgs -> IfaceAppArgs -> Bool
== :: IfaceAppArgs -> IfaceAppArgs -> Bool
$c/= :: IfaceAppArgs -> IfaceAppArgs -> Bool
/= :: IfaceAppArgs -> IfaceAppArgs -> Bool
Eq, Eq IfaceAppArgs
Eq IfaceAppArgs =>
(IfaceAppArgs -> IfaceAppArgs -> Ordering)
-> (IfaceAppArgs -> IfaceAppArgs -> Bool)
-> (IfaceAppArgs -> IfaceAppArgs -> Bool)
-> (IfaceAppArgs -> IfaceAppArgs -> Bool)
-> (IfaceAppArgs -> IfaceAppArgs -> Bool)
-> (IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs)
-> (IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs)
-> Ord IfaceAppArgs
IfaceAppArgs -> IfaceAppArgs -> Bool
IfaceAppArgs -> IfaceAppArgs -> Ordering
IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceAppArgs -> IfaceAppArgs -> Ordering
compare :: IfaceAppArgs -> IfaceAppArgs -> Ordering
$c< :: IfaceAppArgs -> IfaceAppArgs -> Bool
< :: IfaceAppArgs -> IfaceAppArgs -> Bool
$c<= :: IfaceAppArgs -> IfaceAppArgs -> Bool
<= :: IfaceAppArgs -> IfaceAppArgs -> Bool
$c> :: IfaceAppArgs -> IfaceAppArgs -> Bool
> :: IfaceAppArgs -> IfaceAppArgs -> Bool
$c>= :: IfaceAppArgs -> IfaceAppArgs -> Bool
>= :: IfaceAppArgs -> IfaceAppArgs -> Bool
$cmax :: IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
max :: IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
$cmin :: IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
min :: IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
Ord)

instance Semi.Semigroup IfaceAppArgs where
  IfaceAppArgs
IA_Nil <> :: IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
<> IfaceAppArgs
xs              = IfaceAppArgs
xs
  IA_Arg IfaceType
ty ForAllTyFlag
argf IfaceAppArgs
rest <> IfaceAppArgs
xs = IfaceType -> ForAllTyFlag -> IfaceAppArgs -> IfaceAppArgs
IA_Arg IfaceType
ty ForAllTyFlag
argf (IfaceAppArgs
rest IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
forall a. Semigroup a => a -> a -> a
Semi.<> IfaceAppArgs
xs)

instance Monoid IfaceAppArgs where
  mempty :: IfaceAppArgs
mempty = IfaceAppArgs
IA_Nil
  mappend :: IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
mappend = IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
forall a. Semigroup a => a -> a -> a
(Semi.<>)

-- Encodes type constructors, kind constructors,
-- coercion constructors, the lot.
-- We have to tag them in order to pretty print them
-- properly.
data IfaceTyCon = IfaceTyCon { IfaceTyCon -> IfExtName
ifaceTyConName :: IfExtName
                             , IfaceTyCon -> IfaceTyConInfo
ifaceTyConInfo :: !IfaceTyConInfo
                             -- ^ We add a bang to this field as heap analysis
                             -- showed that this constructor retains a thunk to
                             -- a value that is usually shared.
                             --
                             -- See !12200 for how this bang saved ~10% residency
                             -- when loading 'mi_extra_decls' on the agda
                             -- code base.
                             --
                             -- See Note [Sharing IfaceTyConInfo] for why
                             -- sharing is so important for 'IfaceTyConInfo'.
                             }
    deriving (IfaceTyCon -> IfaceTyCon -> Bool
(IfaceTyCon -> IfaceTyCon -> Bool)
-> (IfaceTyCon -> IfaceTyCon -> Bool) -> Eq IfaceTyCon
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceTyCon -> IfaceTyCon -> Bool
== :: IfaceTyCon -> IfaceTyCon -> Bool
$c/= :: IfaceTyCon -> IfaceTyCon -> Bool
/= :: IfaceTyCon -> IfaceTyCon -> Bool
Eq, Eq IfaceTyCon
Eq IfaceTyCon =>
(IfaceTyCon -> IfaceTyCon -> Ordering)
-> (IfaceTyCon -> IfaceTyCon -> Bool)
-> (IfaceTyCon -> IfaceTyCon -> Bool)
-> (IfaceTyCon -> IfaceTyCon -> Bool)
-> (IfaceTyCon -> IfaceTyCon -> Bool)
-> (IfaceTyCon -> IfaceTyCon -> IfaceTyCon)
-> (IfaceTyCon -> IfaceTyCon -> IfaceTyCon)
-> Ord IfaceTyCon
IfaceTyCon -> IfaceTyCon -> Bool
IfaceTyCon -> IfaceTyCon -> Ordering
IfaceTyCon -> IfaceTyCon -> IfaceTyCon
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceTyCon -> IfaceTyCon -> Ordering
compare :: IfaceTyCon -> IfaceTyCon -> Ordering
$c< :: IfaceTyCon -> IfaceTyCon -> Bool
< :: IfaceTyCon -> IfaceTyCon -> Bool
$c<= :: IfaceTyCon -> IfaceTyCon -> Bool
<= :: IfaceTyCon -> IfaceTyCon -> Bool
$c> :: IfaceTyCon -> IfaceTyCon -> Bool
> :: IfaceTyCon -> IfaceTyCon -> Bool
$c>= :: IfaceTyCon -> IfaceTyCon -> Bool
>= :: IfaceTyCon -> IfaceTyCon -> Bool
$cmax :: IfaceTyCon -> IfaceTyCon -> IfaceTyCon
max :: IfaceTyCon -> IfaceTyCon -> IfaceTyCon
$cmin :: IfaceTyCon -> IfaceTyCon -> IfaceTyCon
min :: IfaceTyCon -> IfaceTyCon -> IfaceTyCon
Ord)

-- | The various types of TyCons which have special, built-in syntax.
data IfaceTyConSort = IfaceNormalTyCon          -- ^ a regular tycon

                    | IfaceTupleTyCon !Arity !TupleSort
                      -- ^ a tuple, e.g. @(a, b, c)@ or @(#a, b, c#)@.
                      -- The arity is the tuple width, not the tycon arity
                      -- (which is twice the width in the case of unboxed
                      -- tuples).

                    | IfaceSumTyCon !Arity
                      -- ^ an unboxed sum, e.g. @(# a | b | c #)@

                    | IfaceEqualityTyCon
                      -- ^ A heterogeneous equality TyCon
                      --   (i.e. eqPrimTyCon, eqReprPrimTyCon, heqTyCon)
                      -- that is actually being applied to two types
                      -- of the same kind.  This affects pretty-printing
                      -- only: see Note [Equality predicates in IfaceType]
                    deriving (IfaceTyConSort -> IfaceTyConSort -> Bool
(IfaceTyConSort -> IfaceTyConSort -> Bool)
-> (IfaceTyConSort -> IfaceTyConSort -> Bool) -> Eq IfaceTyConSort
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceTyConSort -> IfaceTyConSort -> Bool
== :: IfaceTyConSort -> IfaceTyConSort -> Bool
$c/= :: IfaceTyConSort -> IfaceTyConSort -> Bool
/= :: IfaceTyConSort -> IfaceTyConSort -> Bool
Eq, Eq IfaceTyConSort
Eq IfaceTyConSort =>
(IfaceTyConSort -> IfaceTyConSort -> Ordering)
-> (IfaceTyConSort -> IfaceTyConSort -> Bool)
-> (IfaceTyConSort -> IfaceTyConSort -> Bool)
-> (IfaceTyConSort -> IfaceTyConSort -> Bool)
-> (IfaceTyConSort -> IfaceTyConSort -> Bool)
-> (IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort)
-> (IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort)
-> Ord IfaceTyConSort
IfaceTyConSort -> IfaceTyConSort -> Bool
IfaceTyConSort -> IfaceTyConSort -> Ordering
IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceTyConSort -> IfaceTyConSort -> Ordering
compare :: IfaceTyConSort -> IfaceTyConSort -> Ordering
$c< :: IfaceTyConSort -> IfaceTyConSort -> Bool
< :: IfaceTyConSort -> IfaceTyConSort -> Bool
$c<= :: IfaceTyConSort -> IfaceTyConSort -> Bool
<= :: IfaceTyConSort -> IfaceTyConSort -> Bool
$c> :: IfaceTyConSort -> IfaceTyConSort -> Bool
> :: IfaceTyConSort -> IfaceTyConSort -> Bool
$c>= :: IfaceTyConSort -> IfaceTyConSort -> Bool
>= :: IfaceTyConSort -> IfaceTyConSort -> Bool
$cmax :: IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort
max :: IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort
$cmin :: IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort
min :: IfaceTyConSort -> IfaceTyConSort -> IfaceTyConSort
Ord)

instance Outputable IfaceTyConSort where
  ppr :: IfaceTyConSort -> SDoc
ppr IfaceTyConSort
IfaceNormalTyCon         = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"normal"
  ppr (IfaceTupleTyCon Int
n TupleSort
sort) = TupleSort -> SDoc
forall a. Outputable a => a -> SDoc
ppr TupleSort
sort SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n
  ppr (IfaceSumTyCon Int
n)        = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"sum:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n
  ppr IfaceTyConSort
IfaceEqualityTyCon       = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"equality"

{- Note [Free TyVars and CoVars in IfaceType]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Nowadays (since Nov 16, 2016) we pretty-print a Type by converting to
an IfaceType and pretty printing that.  This eliminates a lot of
pretty-print duplication, and it matches what we do with pretty-
printing TyThings. See Note [Pretty printing via Iface syntax] in GHC.Types.TyThing.Ppr.

It works fine for closed types, but when printing debug traces (e.g.
when using -ddump-tc-trace) we print a lot of /open/ types.  These
types are full of TcTyVars, and it's absolutely crucial to print them
in their full glory, with their unique, TcTyVarDetails etc.

So we simply embed a TyVar in IfaceType with the IfaceFreeTyVar constructor.
Note that:

* We never expect to serialise an IfaceFreeTyVar into an interface file, nor
  to deserialise one.  IfaceFreeTyVar is used only in the "convert to IfaceType
  and then pretty-print" pipeline.

We do the same for covars, naturally.

Note [Equality predicates in IfaceType]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GHC has several varieties of type equality (see Note [The equality types story]
in GHC.Builtin.Types.Prim for details).  In an effort to avoid confusing users, we suppress
the differences during pretty printing unless certain flags are enabled.
Here is how each equality predicate* is printed in homogeneous and
heterogeneous contexts, depending on which combination of the
-fprint-explicit-kinds and -fprint-equality-relations flags is used:

--------------------------------------------------------------------------------------------
|         Predicate             |        Neither flag        |    -fprint-explicit-kinds   |
|-------------------------------|----------------------------|-----------------------------|
| a ~ b         (homogeneous)   |        a ~ b               | (a :: Type) ~  (b :: Type)  |
| a ~~ b,       homogeneously   |        a ~ b               | (a :: Type) ~  (b :: Type)  |
| a ~~ b,       heterogeneously |        a ~~ c              | (a :: Type) ~~ (c :: k)     |
| a ~# b,       homogeneously   |        a ~ b               | (a :: Type) ~  (b :: Type)  |
| a ~# b,       heterogeneously |        a ~~ c              | (a :: Type) ~~ (c :: k)     |
| Coercible a b (homogeneous)   |        Coercible a b       | Coercible @Type a b         |
| a ~R# b,      homogeneously   |        Coercible a b       | Coercible @Type a b         |
| a ~R# b,      heterogeneously |        a ~R# b             | (a :: Type) ~R# (c :: k)    |
|-------------------------------|----------------------------|-----------------------------|
|         Predicate             | -fprint-equality-relations |          Both flags         |
|-------------------------------|----------------------------|-----------------------------|
| a ~ b         (homogeneous)   |        a ~  b              | (a :: Type) ~  (b :: Type)  |
| a ~~ b,       homogeneously   |        a ~~ b              | (a :: Type) ~~ (b :: Type)  |
| a ~~ b,       heterogeneously |        a ~~ c              | (a :: Type) ~~ (c :: k)     |
| a ~# b,       homogeneously   |        a ~# b              | (a :: Type) ~# (b :: Type)  |
| a ~# b,       heterogeneously |        a ~# c              | (a :: Type) ~# (c :: k)     |
| Coercible a b (homogeneous)   |        Coercible a b       | Coercible @Type a b         |
| a ~R# b,      homogeneously   |        a ~R# b             | (a :: Type) ~R# (b :: Type) |
| a ~R# b,      heterogeneously |        a ~R# b             | (a :: Type) ~R# (c :: k)    |
--------------------------------------------------------------------------------------------

(* There is no heterogeneous, representational, lifted equality counterpart
to (~~). There could be, but there seems to be no use for it.)

This table adheres to the following rules:

A. With -fprint-equality-relations, print the true equality relation.
B. Without -fprint-equality-relations:
     i. If the equality is representational and homogeneous, use Coercible.
    ii. Otherwise, if the equality is representational, use ~R#.
   iii. If the equality is nominal and homogeneous, use ~.
    iv. Otherwise, if the equality is nominal, use ~~.
C. With -fprint-explicit-kinds, print kinds on both sides of an infix operator,
   as above; or print the kind with Coercible.
D. Without -fprint-explicit-kinds, don't print kinds.

A hetero-kinded equality is used homogeneously when it is applied to two
identical kinds. Unfortunately, determining this from an IfaceType isn't
possible since we can't see through type synonyms. Consequently, we need to
record whether this particular application is homogeneous in IfaceTyConSort
for the purposes of pretty-printing.

See Note [The equality types story] in GHC.Builtin.Types.Prim.
-}

data IfaceTyConInfo   -- Used only to guide pretty-printing
  = IfaceTyConInfo { IfaceTyConInfo -> PromotionFlag
ifaceTyConIsPromoted :: PromotionFlag
                      -- A PromotionFlag value of IsPromoted indicates
                      -- that the type constructor came from a data
                      -- constructor promoted by -XDataKinds, and thus
                      -- should be printed as 'D to distinguish it from
                      -- an existing type constructor D.
                   , IfaceTyConInfo -> IfaceTyConSort
ifaceTyConSort       :: IfaceTyConSort }
    deriving (IfaceTyConInfo -> IfaceTyConInfo -> Bool
(IfaceTyConInfo -> IfaceTyConInfo -> Bool)
-> (IfaceTyConInfo -> IfaceTyConInfo -> Bool) -> Eq IfaceTyConInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
== :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
$c/= :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
/= :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
Eq, Eq IfaceTyConInfo
Eq IfaceTyConInfo =>
(IfaceTyConInfo -> IfaceTyConInfo -> Ordering)
-> (IfaceTyConInfo -> IfaceTyConInfo -> Bool)
-> (IfaceTyConInfo -> IfaceTyConInfo -> Bool)
-> (IfaceTyConInfo -> IfaceTyConInfo -> Bool)
-> (IfaceTyConInfo -> IfaceTyConInfo -> Bool)
-> (IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo)
-> (IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo)
-> Ord IfaceTyConInfo
IfaceTyConInfo -> IfaceTyConInfo -> Bool
IfaceTyConInfo -> IfaceTyConInfo -> Ordering
IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceTyConInfo -> IfaceTyConInfo -> Ordering
compare :: IfaceTyConInfo -> IfaceTyConInfo -> Ordering
$c< :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
< :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
$c<= :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
<= :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
$c> :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
> :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
$c>= :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
>= :: IfaceTyConInfo -> IfaceTyConInfo -> Bool
$cmax :: IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo
max :: IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo
$cmin :: IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo
min :: IfaceTyConInfo -> IfaceTyConInfo -> IfaceTyConInfo
Ord)

-- | This smart constructor allows sharing of the two most common
-- cases. See Note [Sharing IfaceTyConInfo]
mkIfaceTyConInfo :: PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo :: PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo PromotionFlag
IsPromoted  IfaceTyConSort
IfaceNormalTyCon = IfaceTyConInfo
promotedNormalTyConInfo
mkIfaceTyConInfo PromotionFlag
NotPromoted IfaceTyConSort
IfaceNormalTyCon = IfaceTyConInfo
notPromotedNormalTyConInfo
mkIfaceTyConInfo PromotionFlag
prom        IfaceTyConSort
sort             = PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
IfaceTyConInfo PromotionFlag
prom IfaceTyConSort
sort

{-# NOINLINE promotedNormalTyConInfo #-}
-- | See Note [Sharing IfaceTyConInfo]
promotedNormalTyConInfo :: IfaceTyConInfo
promotedNormalTyConInfo :: IfaceTyConInfo
promotedNormalTyConInfo = PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
IfaceTyConInfo PromotionFlag
IsPromoted IfaceTyConSort
IfaceNormalTyCon

{-# NOINLINE notPromotedNormalTyConInfo #-}
-- | See Note [Sharing IfaceTyConInfo]
notPromotedNormalTyConInfo :: IfaceTyConInfo
notPromotedNormalTyConInfo :: IfaceTyConInfo
notPromotedNormalTyConInfo = PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
IfaceTyConInfo PromotionFlag
NotPromoted IfaceTyConSort
IfaceNormalTyCon

{-
Note [Sharing IfaceTyConInfo]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'IfaceTyConInfo' occurs an awful lot in 'ModIface', see #19194 for an example.
But almost all of them are

   IfaceTyConInfo IsPromoted IfaceNormalTyCon
   IfaceTyConInfo NotPromoted IfaceNormalTyCon.

The smart constructor `mkIfaceTyConInfo` arranges to share these instances,
thus:

  promotedNormalTyConInfo    = IfaceTyConInfo IsPromoted  IfaceNormalTyCon
  notPromotedNormalTyConInfo = IfaceTyConInfo NotPromoted IfaceNormalTyCon

  mkIfaceTyConInfo IsPromoted  IfaceNormalTyCon = promotedNormalTyConInfo
  mkIfaceTyConInfo NotPromoted IfaceNormalTyCon = notPromotedNormalTyConInfo
  mkIfaceTyConInfo prom        sort             = IfaceTyConInfo prom sort

But ALAS, the (nested) CPR transform can lose this sharing, completely
negating the effect of `mkIfaceTyConInfo`: see #24530 and #19326.

Sticking-plaster solution: add a NOINLINE pragma to those top-level constants.
When we fix the CPR bug we can remove the NOINLINE pragmas.

This one change leads to an 15% reduction in residency for GHC when embedding
'mi_extra_decls': see !12222.
-}

data IfaceMCoercion
  = IfaceMRefl
  | IfaceMCo IfaceCoercion deriving (IfaceMCoercion -> IfaceMCoercion -> Bool
(IfaceMCoercion -> IfaceMCoercion -> Bool)
-> (IfaceMCoercion -> IfaceMCoercion -> Bool) -> Eq IfaceMCoercion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceMCoercion -> IfaceMCoercion -> Bool
== :: IfaceMCoercion -> IfaceMCoercion -> Bool
$c/= :: IfaceMCoercion -> IfaceMCoercion -> Bool
/= :: IfaceMCoercion -> IfaceMCoercion -> Bool
Eq, Eq IfaceMCoercion
Eq IfaceMCoercion =>
(IfaceMCoercion -> IfaceMCoercion -> Ordering)
-> (IfaceMCoercion -> IfaceMCoercion -> Bool)
-> (IfaceMCoercion -> IfaceMCoercion -> Bool)
-> (IfaceMCoercion -> IfaceMCoercion -> Bool)
-> (IfaceMCoercion -> IfaceMCoercion -> Bool)
-> (IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion)
-> (IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion)
-> Ord IfaceMCoercion
IfaceMCoercion -> IfaceMCoercion -> Bool
IfaceMCoercion -> IfaceMCoercion -> Ordering
IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceMCoercion -> IfaceMCoercion -> Ordering
compare :: IfaceMCoercion -> IfaceMCoercion -> Ordering
$c< :: IfaceMCoercion -> IfaceMCoercion -> Bool
< :: IfaceMCoercion -> IfaceMCoercion -> Bool
$c<= :: IfaceMCoercion -> IfaceMCoercion -> Bool
<= :: IfaceMCoercion -> IfaceMCoercion -> Bool
$c> :: IfaceMCoercion -> IfaceMCoercion -> Bool
> :: IfaceMCoercion -> IfaceMCoercion -> Bool
$c>= :: IfaceMCoercion -> IfaceMCoercion -> Bool
>= :: IfaceMCoercion -> IfaceMCoercion -> Bool
$cmax :: IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion
max :: IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion
$cmin :: IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion
min :: IfaceMCoercion -> IfaceMCoercion -> IfaceMCoercion
Ord)

data IfaceCoercion
  = IfaceReflCo       IfaceType
  | IfaceGReflCo      Role IfaceType (IfaceMCoercion)
  | IfaceFunCo        Role IfaceCoercion IfaceCoercion IfaceCoercion
  | IfaceTyConAppCo   Role IfaceTyCon [IfaceCoercion]
  | IfaceAppCo        IfaceCoercion IfaceCoercion
  | IfaceForAllCo     IfaceBndr !ForAllTyFlag !ForAllTyFlag IfaceCoercion IfaceCoercion
  | IfaceCoVarCo      IfLclName
  | IfaceAxiomCo      IfaceAxiomRule [IfaceCoercion]
       -- ^ There are only a fixed number of CoAxiomRules, so it suffices
       -- to use an IfaceLclName to distinguish them.
       -- See Note [Adding built-in type families] in GHC.Builtin.Types.Literals
  | IfaceUnivCo       UnivCoProvenance Role IfaceType IfaceType [IfaceCoercion]
  | IfaceSymCo        IfaceCoercion
  | IfaceTransCo      IfaceCoercion IfaceCoercion
  | IfaceSelCo        CoSel IfaceCoercion
  | IfaceLRCo         LeftOrRight IfaceCoercion
  | IfaceInstCo       IfaceCoercion IfaceCoercion
  | IfaceKindCo       IfaceCoercion
  | IfaceSubCo        IfaceCoercion
  | IfaceFreeCoVar    CoVar    -- ^ See Note [Free TyVars and CoVars in IfaceType]
  | IfaceHoleCo       CoVar    -- ^ See Note [Holes in IfaceCoercion]
  deriving (IfaceCoercion -> IfaceCoercion -> Bool
(IfaceCoercion -> IfaceCoercion -> Bool)
-> (IfaceCoercion -> IfaceCoercion -> Bool) -> Eq IfaceCoercion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceCoercion -> IfaceCoercion -> Bool
== :: IfaceCoercion -> IfaceCoercion -> Bool
$c/= :: IfaceCoercion -> IfaceCoercion -> Bool
/= :: IfaceCoercion -> IfaceCoercion -> Bool
Eq, Eq IfaceCoercion
Eq IfaceCoercion =>
(IfaceCoercion -> IfaceCoercion -> Ordering)
-> (IfaceCoercion -> IfaceCoercion -> Bool)
-> (IfaceCoercion -> IfaceCoercion -> Bool)
-> (IfaceCoercion -> IfaceCoercion -> Bool)
-> (IfaceCoercion -> IfaceCoercion -> Bool)
-> (IfaceCoercion -> IfaceCoercion -> IfaceCoercion)
-> (IfaceCoercion -> IfaceCoercion -> IfaceCoercion)
-> Ord IfaceCoercion
IfaceCoercion -> IfaceCoercion -> Bool
IfaceCoercion -> IfaceCoercion -> Ordering
IfaceCoercion -> IfaceCoercion -> IfaceCoercion
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceCoercion -> IfaceCoercion -> Ordering
compare :: IfaceCoercion -> IfaceCoercion -> Ordering
$c< :: IfaceCoercion -> IfaceCoercion -> Bool
< :: IfaceCoercion -> IfaceCoercion -> Bool
$c<= :: IfaceCoercion -> IfaceCoercion -> Bool
<= :: IfaceCoercion -> IfaceCoercion -> Bool
$c> :: IfaceCoercion -> IfaceCoercion -> Bool
> :: IfaceCoercion -> IfaceCoercion -> Bool
$c>= :: IfaceCoercion -> IfaceCoercion -> Bool
>= :: IfaceCoercion -> IfaceCoercion -> Bool
$cmax :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
max :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
$cmin :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
min :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
Ord)
  -- Why Ord?  See Note [Ord instance of IfaceType]

data IfaceAxiomRule
  = IfaceAR_X IfLclName               -- Built-in
  | IfaceAR_B IfExtName BranchIndex   -- Branched
  | IfaceAR_U IfExtName               -- Unbranched
  deriving (IfaceAxiomRule -> IfaceAxiomRule -> Bool
(IfaceAxiomRule -> IfaceAxiomRule -> Bool)
-> (IfaceAxiomRule -> IfaceAxiomRule -> Bool) -> Eq IfaceAxiomRule
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
== :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
$c/= :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
/= :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
Eq, Eq IfaceAxiomRule
Eq IfaceAxiomRule =>
(IfaceAxiomRule -> IfaceAxiomRule -> Ordering)
-> (IfaceAxiomRule -> IfaceAxiomRule -> Bool)
-> (IfaceAxiomRule -> IfaceAxiomRule -> Bool)
-> (IfaceAxiomRule -> IfaceAxiomRule -> Bool)
-> (IfaceAxiomRule -> IfaceAxiomRule -> Bool)
-> (IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule)
-> (IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule)
-> Ord IfaceAxiomRule
IfaceAxiomRule -> IfaceAxiomRule -> Bool
IfaceAxiomRule -> IfaceAxiomRule -> Ordering
IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IfaceAxiomRule -> IfaceAxiomRule -> Ordering
compare :: IfaceAxiomRule -> IfaceAxiomRule -> Ordering
$c< :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
< :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
$c<= :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
<= :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
$c> :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
> :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
$c>= :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
>= :: IfaceAxiomRule -> IfaceAxiomRule -> Bool
$cmax :: IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule
max :: IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule
$cmin :: IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule
min :: IfaceAxiomRule -> IfaceAxiomRule -> IfaceAxiomRule
Ord)

{- Note [Holes in IfaceCoercion]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When typechecking fails the typechecker will produce a HoleCo to stand
in place of the unproven assertion. While we generally don't want to
let these unproven assertions leak into interface files, we still need
to be able to pretty-print them as we use IfaceType's pretty-printer
to render Types. For this reason IfaceCoercion has a IfaceHoleCo
constructor; however, we fails when asked to serialize to a
IfaceHoleCo to ensure that they don't end up in an interface file.


%************************************************************************
%*                                                                      *
                Functions over IfaceTypes
*                                                                      *
************************************************************************
-}

ifaceTyConHasKey :: IfaceTyCon -> Unique -> Bool
ifaceTyConHasKey :: IfaceTyCon -> Unique -> Bool
ifaceTyConHasKey IfaceTyCon
tc Unique
key = IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
key

-- | Returns true for Type or (TYPE LiftedRep)
isIfaceLiftedTypeKind :: IfaceKind -> Bool
isIfaceLiftedTypeKind :: IfaceType -> Bool
isIfaceLiftedTypeKind (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
args)
  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
liftedTypeKindTyConKey
  , IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  = Bool
True  -- Type

  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
tYPETyConKey
  , IA_Arg IfaceType
arg1 ForAllTyFlag
Required IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  , IfaceType -> Bool
isIfaceLiftedRep IfaceType
arg1
  = Bool
True  -- TYPE Lifted

isIfaceLiftedTypeKind IfaceType
_ = Bool
False

-- | Returns true for Constraint or (CONSTRAINT LiftedRep)
isIfaceConstraintKind :: IfaceKind -> Bool
isIfaceConstraintKind :: IfaceType -> Bool
isIfaceConstraintKind (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
args)
  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
constraintKindTyConKey
  , IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  = Bool
True  -- Type

  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
cONSTRAINTTyConKey
  , IA_Arg IfaceType
arg1 ForAllTyFlag
Required IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  , IfaceType -> Bool
isIfaceLiftedRep IfaceType
arg1
  = Bool
True  -- TYPE Lifted

isIfaceConstraintKind IfaceType
_ = Bool
False

isIfaceLiftedRep :: IfaceKind -> Bool
-- Returns true for LiftedRep, or BoxedRep Lifted
isIfaceLiftedRep :: IfaceType -> Bool
isIfaceLiftedRep (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
args)
  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
liftedRepTyConKey
  , IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  = Bool
True  -- LiftedRep

  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
boxedRepDataConKey
  , IA_Arg IfaceType
arg1 ForAllTyFlag
Required IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  , IfaceType -> Bool
isIfaceLifted IfaceType
arg1
  = Bool
True  -- TYPE Lifted

isIfaceLiftedRep IfaceType
_ = Bool
False

isIfaceLifted :: IfaceKind -> Bool
-- Returns true for Lifted
isIfaceLifted :: IfaceType -> Bool
isIfaceLifted (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
args)
  | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
liftedDataConKey
  , IfaceAppArgs
IA_Nil <- IfaceAppArgs
args
  = Bool
True
isIfaceLifted IfaceType
_ = Bool
False

splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfacePredType], IfaceType)
-- Mainly for printing purposes
--
-- Here we split nested IfaceSigmaTy properly.
--
-- @
-- forall t. T t => forall m a b. M m => (a -> m b) -> t a -> m (t b)
-- @
--
-- If you called @splitIfaceSigmaTy@ on this type:
--
-- @
-- ([t, m, a, b], [T t, M m], (a -> m b) -> t a -> m (t b))
-- @
splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfaceType], IfaceType)
splitIfaceSigmaTy IfaceType
ty
  = case ([IfaceForAllBndr]
bndrs, [IfaceType]
theta) of
      ([], []) -> ([IfaceForAllBndr]
bndrs, [IfaceType]
theta, IfaceType
tau)
      ([IfaceForAllBndr], [IfaceType])
_        -> let ([IfaceForAllBndr]
bndrs', [IfaceType]
theta', IfaceType
tau') = IfaceType -> ([IfaceForAllBndr], [IfaceType], IfaceType)
splitIfaceSigmaTy IfaceType
tau
                   in ([IfaceForAllBndr]
bndrs [IfaceForAllBndr] -> [IfaceForAllBndr] -> [IfaceForAllBndr]
forall a. [a] -> [a] -> [a]
++ [IfaceForAllBndr]
bndrs', [IfaceType]
theta [IfaceType] -> [IfaceType] -> [IfaceType]
forall a. [a] -> [a] -> [a]
++ [IfaceType]
theta', IfaceType
tau')
  where
    ([IfaceForAllBndr]
bndrs, IfaceType
rho)   = IfaceType -> ([IfaceForAllBndr], IfaceType)
split_foralls IfaceType
ty
    ([IfaceType]
theta, IfaceType
tau)   = IfaceType -> ([IfaceType], IfaceType)
split_rho IfaceType
rho

    split_foralls :: IfaceType -> ([IfaceForAllBndr], IfaceType)
split_foralls (IfaceForAllTy IfaceForAllBndr
bndr IfaceType
ty)
        | ForAllTyFlag -> Bool
isInvisibleForAllTyFlag (IfaceForAllBndr -> ForAllTyFlag
forall tv argf. VarBndr tv argf -> argf
binderFlag IfaceForAllBndr
bndr)
        = case IfaceType -> ([IfaceForAllBndr], IfaceType)
split_foralls IfaceType
ty of { ([IfaceForAllBndr]
bndrs, IfaceType
rho) -> (IfaceForAllBndr
bndrIfaceForAllBndr -> [IfaceForAllBndr] -> [IfaceForAllBndr]
forall a. a -> [a] -> [a]
:[IfaceForAllBndr]
bndrs, IfaceType
rho) }
    split_foralls IfaceType
rho = ([], IfaceType
rho)

    split_rho :: IfaceType -> ([IfaceType], IfaceType)
split_rho (IfaceFunTy FunTyFlag
af IfaceType
_ IfaceType
ty1 IfaceType
ty2)
        | FunTyFlag -> Bool
isInvisibleFunArg FunTyFlag
af
        = case IfaceType -> ([IfaceType], IfaceType)
split_rho IfaceType
ty2 of { ([IfaceType]
ps, IfaceType
tau) -> (IfaceType
ty1IfaceType -> [IfaceType] -> [IfaceType]
forall a. a -> [a] -> [a]
:[IfaceType]
ps, IfaceType
tau) }
    split_rho IfaceType
tau = ([], IfaceType
tau)

splitIfaceReqForallTy :: IfaceType -> ([IfaceForAllBndr], IfaceType)
splitIfaceReqForallTy :: IfaceType -> ([IfaceForAllBndr], IfaceType)
splitIfaceReqForallTy (IfaceForAllTy IfaceForAllBndr
bndr IfaceType
ty)
  | ForAllTyFlag -> Bool
isVisibleForAllTyFlag (IfaceForAllBndr -> ForAllTyFlag
forall tv argf. VarBndr tv argf -> argf
binderFlag IfaceForAllBndr
bndr)
  = case IfaceType -> ([IfaceForAllBndr], IfaceType)
splitIfaceReqForallTy IfaceType
ty of { ([IfaceForAllBndr]
bndrs, IfaceType
rho) -> (IfaceForAllBndr
bndrIfaceForAllBndr -> [IfaceForAllBndr] -> [IfaceForAllBndr]
forall a. a -> [a] -> [a]
:[IfaceForAllBndr]
bndrs, IfaceType
rho) }
splitIfaceReqForallTy IfaceType
rho = ([], IfaceType
rho)

newtype PrintArityInvisibles = MkPrintArityInvisibles Bool

-- See Note [Print invisible binders in interface declarations]
-- for the definition of what binders are considered insignificant
suppressIfaceInvisibles :: PrintArityInvisibles
                        -> PrintExplicitKinds
                        -> Set.Set IfLclName
                        -> [IfaceTyConBinder]
                        -> [a]
                        -> [a]
suppressIfaceInvisibles :: forall a.
PrintArityInvisibles
-> PrintExplicitKinds
-> Set IfLclName
-> [IfaceTyConBinder]
-> [a]
-> [a]
suppressIfaceInvisibles PrintArityInvisibles
_ (PrintExplicitKinds Bool
True) Set IfLclName
_ [IfaceTyConBinder]
_tys [a]
xs = [a]
xs

suppressIfaceInvisibles -- This case is semantically the same as the third case, but it should be way f
  (MkPrintArityInvisibles Bool
False) (PrintExplicitKinds Bool
False) Set IfLclName
mentioned_vars [IfaceTyConBinder]
tys [a]
xs
  | Set IfLclName -> Bool
forall a. Set a -> Bool
Set.null Set IfLclName
mentioned_vars = [IfaceTyConBinder] -> [a] -> [a]
forall {tv} {a}. [VarBndr tv TyConBndrVis] -> [a] -> [a]
suppress [IfaceTyConBinder]
tys [a]
xs
    where
      suppress :: [VarBndr tv TyConBndrVis] -> [a] -> [a]
suppress [VarBndr tv TyConBndrVis]
_       []      = []
      suppress []      [a]
a       = [a]
a
      suppress (VarBndr tv TyConBndrVis
k:[VarBndr tv TyConBndrVis]
ks) (a
x:[a]
xs)
        | VarBndr tv TyConBndrVis -> Bool
forall tv. VarBndr tv TyConBndrVis -> Bool
isInvisibleTyConBinder VarBndr tv TyConBndrVis
k =     [VarBndr tv TyConBndrVis] -> [a] -> [a]
suppress [VarBndr tv TyConBndrVis]
ks [a]
xs
        | Bool
otherwise                = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [VarBndr tv TyConBndrVis] -> [a] -> [a]
suppress [VarBndr tv TyConBndrVis]
ks [a]
xs

suppressIfaceInvisibles
  (MkPrintArityInvisibles Bool
arity_invisibles)
  (PrintExplicitKinds Bool
False) Set IfLclName
mentioned_vars [IfaceTyConBinder]
tys [a]
xs
  = ((IfaceTyConBinder, a) -> a) -> [(IfaceTyConBinder, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (IfaceTyConBinder, a) -> a
forall a b. (a, b) -> b
snd ([(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
suppress ([IfaceTyConBinder] -> [a] -> [(IfaceTyConBinder, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [IfaceTyConBinder]
tys [a]
xs))
    where
      -- Consider this example:
      --   type T :: forall k1 k2. Type
      --   type T @a @b = b
      -- `@a` is not mentioned on the RHS. However, we can't just
      -- drop it because implicit argument positioning matters.
      --
      -- Hence just drop the end
      only_mentioned_binders :: [(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
only_mentioned_binders = ((IfaceTyConBinder, a) -> Bool)
-> [(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd (Bool -> Bool
not (Bool -> Bool)
-> ((IfaceTyConBinder, a) -> Bool) -> (IfaceTyConBinder, a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IfaceTyConBinder, a) -> Bool
is_binder_mentioned)

      is_binder_mentioned :: (IfaceTyConBinder, a) -> Bool
is_binder_mentioned (IfaceTyConBinder
bndr, a
_) = IfaceTyConBinder -> IfLclName
ifTyConBinderName IfaceTyConBinder
bndr IfLclName -> Set IfLclName -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set IfLclName
mentioned_vars

      suppress_invisibles :: NonEmpty (IfaceTyConBinder, a) -> [(IfaceTyConBinder, a)]
suppress_invisibles NonEmpty (IfaceTyConBinder, a)
group =
        Bool
-> ([(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)])
-> [(IfaceTyConBinder, a)]
-> [(IfaceTyConBinder, a)]
forall a. Bool -> (a -> a) -> a -> a
applyWhen Bool
invis_group [(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
only_mentioned_binders [(IfaceTyConBinder, a)]
bndrs
        where
          bndrs :: [(IfaceTyConBinder, a)]
bndrs       = NonEmpty (IfaceTyConBinder, a) -> [(IfaceTyConBinder, a)]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty (IfaceTyConBinder, a)
group
          invis_group :: Bool
invis_group = (IfaceTyConBinder, a) -> Bool
forall {tv} {b}. (VarBndr tv TyConBndrVis, b) -> Bool
is_invisible_bndr (NonEmpty (IfaceTyConBinder, a) -> (IfaceTyConBinder, a)
forall a. NonEmpty a -> a
NonEmpty.head NonEmpty (IfaceTyConBinder, a)
group)

      suppress_invisible_groups :: [NonEmpty (IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
suppress_invisible_groups [] = []
      suppress_invisible_groups [NonEmpty (IfaceTyConBinder, a)
group] =
          if Bool
arity_invisibles
            then NonEmpty (IfaceTyConBinder, a) -> [(IfaceTyConBinder, a)]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty (IfaceTyConBinder, a)
group -- the last group affects arity
            else NonEmpty (IfaceTyConBinder, a) -> [(IfaceTyConBinder, a)]
suppress_invisibles NonEmpty (IfaceTyConBinder, a)
group
      suppress_invisible_groups (NonEmpty (IfaceTyConBinder, a)
group : [NonEmpty (IfaceTyConBinder, a)]
groups)
        = NonEmpty (IfaceTyConBinder, a) -> [(IfaceTyConBinder, a)]
suppress_invisibles NonEmpty (IfaceTyConBinder, a)
group [(IfaceTyConBinder, a)]
-> [(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
forall a. [a] -> [a] -> [a]
++ [NonEmpty (IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
suppress_invisible_groups [NonEmpty (IfaceTyConBinder, a)]
groups

      suppress :: [(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
suppress
        = [NonEmpty (IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
suppress_invisible_groups            -- Filter out insignificant invisible binders
        ([NonEmpty (IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)])
-> ([(IfaceTyConBinder, a)] -> [NonEmpty (IfaceTyConBinder, a)])
-> [(IfaceTyConBinder, a)]
-> [(IfaceTyConBinder, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((IfaceTyConBinder, a) -> Bool)
-> [(IfaceTyConBinder, a)] -> [NonEmpty (IfaceTyConBinder, a)]
forall (f :: * -> *) b a.
(Foldable f, Eq b) =>
(a -> b) -> f a -> [NonEmpty a]
NonEmpty.groupWith (IfaceTyConBinder, a) -> Bool
forall {tv} {b}. (VarBndr tv TyConBndrVis, b) -> Bool
is_invisible_bndr -- Find chunks of @-binders
        ([(IfaceTyConBinder, a)] -> [NonEmpty (IfaceTyConBinder, a)])
-> ([(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)])
-> [(IfaceTyConBinder, a)]
-> [NonEmpty (IfaceTyConBinder, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((IfaceTyConBinder, a) -> Bool)
-> [(IfaceTyConBinder, a)] -> [(IfaceTyConBinder, a)]
forall a. (a -> Bool) -> [a] -> [a]
filterOut          (IfaceTyConBinder, a) -> Bool
forall {tv} {b}. (VarBndr tv TyConBndrVis, b) -> Bool
is_inferred_bndr  -- We don't want to display @{binders}

      is_inferred_bndr :: (VarBndr var TyConBndrVis, b) -> Bool
is_inferred_bndr = VarBndr var TyConBndrVis -> Bool
forall tv. VarBndr tv TyConBndrVis -> Bool
isInferredTyConBinder (VarBndr var TyConBndrVis -> Bool)
-> ((VarBndr var TyConBndrVis, b) -> VarBndr var TyConBndrVis)
-> (VarBndr var TyConBndrVis, b)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VarBndr var TyConBndrVis, b) -> VarBndr var TyConBndrVis
forall a b. (a, b) -> a
fst
      is_invisible_bndr :: (VarBndr tv TyConBndrVis, b) -> Bool
is_invisible_bndr = VarBndr tv TyConBndrVis -> Bool
forall tv. VarBndr tv TyConBndrVis -> Bool
isInvisibleTyConBinder (VarBndr tv TyConBndrVis -> Bool)
-> ((VarBndr tv TyConBndrVis, b) -> VarBndr tv TyConBndrVis)
-> (VarBndr tv TyConBndrVis, b)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VarBndr tv TyConBndrVis, b) -> VarBndr tv TyConBndrVis
forall a b. (a, b) -> a
fst

stripIfaceInvisVars :: PrintExplicitKinds -> [IfaceTyConBinder] -> [IfaceTyConBinder]
stripIfaceInvisVars :: PrintExplicitKinds -> [IfaceTyConBinder] -> [IfaceTyConBinder]
stripIfaceInvisVars (PrintExplicitKinds Bool
True)  [IfaceTyConBinder]
tyvars = [IfaceTyConBinder]
tyvars
stripIfaceInvisVars (PrintExplicitKinds Bool
False) [IfaceTyConBinder]
tyvars
  = (IfaceTyConBinder -> Bool)
-> [IfaceTyConBinder] -> [IfaceTyConBinder]
forall a. (a -> Bool) -> [a] -> [a]
filterOut IfaceTyConBinder -> Bool
forall tv. VarBndr tv TyConBndrVis -> Bool
isInvisibleTyConBinder [IfaceTyConBinder]
tyvars

-- | Extract an 'IfaceBndr' from an 'IfaceForAllBndr'.
ifForAllBndrVar :: IfaceForAllBndr -> IfaceBndr
ifForAllBndrVar :: IfaceForAllBndr -> IfaceBndr
ifForAllBndrVar = IfaceForAllBndr -> IfaceBndr
forall tv argf. VarBndr tv argf -> tv
binderVar

-- | Extract the variable name from an 'IfaceForAllBndr'.
ifForAllBndrName :: IfaceForAllBndr -> IfLclName
ifForAllBndrName :: IfaceForAllBndr -> IfLclName
ifForAllBndrName IfaceForAllBndr
fab = IfaceBndr -> IfLclName
ifaceBndrName (IfaceForAllBndr -> IfaceBndr
ifForAllBndrVar IfaceForAllBndr
fab)

-- | Extract an 'IfaceBndr' from an 'IfaceTyConBinder'.
ifTyConBinderVar :: IfaceTyConBinder -> IfaceBndr
ifTyConBinderVar :: IfaceTyConBinder -> IfaceBndr
ifTyConBinderVar = IfaceTyConBinder -> IfaceBndr
forall tv argf. VarBndr tv argf -> tv
binderVar

-- | Extract the variable name from an 'IfaceTyConBinder'.
ifTyConBinderName :: IfaceTyConBinder -> IfLclName
ifTyConBinderName :: IfaceTyConBinder -> IfLclName
ifTyConBinderName IfaceTyConBinder
tcb = IfaceBndr -> IfLclName
ifaceBndrName (IfaceTyConBinder -> IfaceBndr
ifTyConBinderVar IfaceTyConBinder
tcb)

ifTypeIsVarFree :: IfaceType -> Bool
-- Returns True if the type definitely has no variables at all
-- Just used to control pretty printing
ifTypeIsVarFree :: IfaceType -> Bool
ifTypeIsVarFree IfaceType
ty = IfaceType -> Bool
go IfaceType
ty
  where
    go :: IfaceType -> Bool
go (IfaceTyVar {})         = Bool
False
    go (IfaceFreeTyVar {})     = Bool
False
    go (IfaceAppTy IfaceType
fun IfaceAppArgs
args)   = IfaceType -> Bool
go IfaceType
fun Bool -> Bool -> Bool
&& IfaceAppArgs -> Bool
go_args IfaceAppArgs
args
    go (IfaceFunTy FunTyFlag
_ IfaceType
w IfaceType
arg IfaceType
res) = IfaceType -> Bool
go IfaceType
w Bool -> Bool -> Bool
&& IfaceType -> Bool
go IfaceType
arg Bool -> Bool -> Bool
&& IfaceType -> Bool
go IfaceType
res
    go (IfaceForAllTy {})      = Bool
False
    go (IfaceTyConApp IfaceTyCon
_ IfaceAppArgs
args)  = IfaceAppArgs -> Bool
go_args IfaceAppArgs
args
    go (IfaceTupleTy TupleSort
_ PromotionFlag
_ IfaceAppArgs
args) = IfaceAppArgs -> Bool
go_args IfaceAppArgs
args
    go (IfaceLitTy IfaceTyLit
_)          = Bool
True
    go (IfaceCastTy {})        = Bool
False -- Safe
    go (IfaceCoercionTy {})    = Bool
False -- Safe

    go_args :: IfaceAppArgs -> Bool
go_args IfaceAppArgs
IA_Nil = Bool
True
    go_args (IA_Arg IfaceType
arg ForAllTyFlag
_ IfaceAppArgs
args) = IfaceType -> Bool
go IfaceType
arg Bool -> Bool -> Bool
&& IfaceAppArgs -> Bool
go_args IfaceAppArgs
args

visibleTypeVarOccurencies :: IfaceType -> Set.Set IfLclName
-- Returns True if the type contains this name. Doesn't count
-- invisible application
-- Just used to control pretty printing
visibleTypeVarOccurencies :: IfaceType -> Set IfLclName
visibleTypeVarOccurencies = IfaceType -> Set IfLclName
go
  where
    <> :: Set IfLclName -> Set IfLclName -> Set IfLclName
(<>) = Set IfLclName -> Set IfLclName -> Set IfLclName
forall a. Ord a => Set a -> Set a -> Set a
Set.union

    go :: IfaceType -> Set IfLclName
go (IfaceTyVar IfLclName
var)         = IfLclName -> Set IfLclName
forall a. a -> Set a
Set.singleton IfLclName
var
    go (IfaceFreeTyVar {})      = Set IfLclName
forall a. Monoid a => a
mempty
    go (IfaceAppTy IfaceType
fun IfaceAppArgs
args)    = IfaceType -> Set IfLclName
go IfaceType
fun Set IfLclName -> Set IfLclName -> Set IfLclName
<> IfaceAppArgs -> Set IfLclName
go_args IfaceAppArgs
args
    go (IfaceFunTy FunTyFlag
_ IfaceType
w IfaceType
arg IfaceType
res) = IfaceType -> Set IfLclName
go IfaceType
w Set IfLclName -> Set IfLclName -> Set IfLclName
<> IfaceType -> Set IfLclName
go IfaceType
arg Set IfLclName -> Set IfLclName -> Set IfLclName
<> IfaceType -> Set IfLclName
go IfaceType
res
    go (IfaceForAllTy IfaceForAllBndr
bndr IfaceType
ty)  = IfaceType -> Set IfLclName
go (IfaceBndr -> IfaceType
ifaceBndrType (IfaceBndr -> IfaceType) -> IfaceBndr -> IfaceType
forall a b. (a -> b) -> a -> b
$ IfaceForAllBndr -> IfaceBndr
forall tv argf. VarBndr tv argf -> tv
binderVar IfaceForAllBndr
bndr) Set IfLclName -> Set IfLclName -> Set IfLclName
<> IfaceType -> Set IfLclName
go IfaceType
ty
    go (IfaceTyConApp IfaceTyCon
_ IfaceAppArgs
args)   = IfaceAppArgs -> Set IfLclName
go_args IfaceAppArgs
args
    go (IfaceTupleTy TupleSort
_ PromotionFlag
_ IfaceAppArgs
args)  = IfaceAppArgs -> Set IfLclName
go_args IfaceAppArgs
args
    go (IfaceLitTy IfaceTyLit
_)           = Set IfLclName
forall a. Monoid a => a
mempty
    go (IfaceCastTy {})         = Set IfLclName
forall a. Monoid a => a
mempty -- Safe
    go (IfaceCoercionTy {})     = Set IfLclName
forall a. Monoid a => a
mempty -- Safe

    go_args :: IfaceAppArgs -> Set IfLclName
go_args IfaceAppArgs
IA_Nil = Set IfLclName
forall a. Monoid a => a
mempty
    go_args (IA_Arg IfaceType
arg ForAllTyFlag
Required IfaceAppArgs
args) = IfaceType -> Set IfLclName
go IfaceType
arg Set IfLclName -> Set IfLclName -> Set IfLclName
<> IfaceAppArgs -> Set IfLclName
go_args IfaceAppArgs
args
    go_args (IA_Arg IfaceType
_arg ForAllTyFlag
_ IfaceAppArgs
args) = IfaceAppArgs -> Set IfLclName
go_args IfaceAppArgs
args

{- Note [Substitution on IfaceType]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Substitutions on IfaceType are done only during pretty-printing to
construct the result type of a GADT, and does not deal with binders
(eg IfaceForAll), so it doesn't need fancy capture stuff.  -}

type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType]

mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst
-- See Note [Substitution on IfaceType]
mkIfaceTySubst :: [IfaceTvBndr] -> IfaceTySubst
mkIfaceTySubst [IfaceTvBndr]
eq_spec = [(FastString, IfaceType)] -> IfaceTySubst
forall a. [(FastString, a)] -> FastStringEnv a
mkFsEnv ((IfaceTvBndr -> (FastString, IfaceType))
-> [IfaceTvBndr] -> [(FastString, IfaceType)]
forall a b. (a -> b) -> [a] -> [b]
map ((IfLclName -> FastString) -> IfaceTvBndr -> (FastString, IfaceType)
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first IfLclName -> FastString
ifLclNameFS) [IfaceTvBndr]
eq_spec)

inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool
-- See Note [Substitution on IfaceType]
inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool
inDomIfaceTySubst IfaceTySubst
subst (IfLclName
fs, IfaceType
_) = Maybe IfaceType -> Bool
forall a. Maybe a -> Bool
isJust (IfaceTySubst -> FastString -> Maybe IfaceType
forall a. FastStringEnv a -> FastString -> Maybe a
lookupFsEnv IfaceTySubst
subst (IfLclName -> FastString
ifLclNameFS IfLclName
fs))

substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType
-- See Note [Substitution on IfaceType]
substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType
substIfaceType IfaceTySubst
env IfaceType
ty
  = IfaceType -> IfaceType
go IfaceType
ty
  where
    go :: IfaceType -> IfaceType
go (IfaceFreeTyVar TyVar
tv)    = TyVar -> IfaceType
IfaceFreeTyVar TyVar
tv
    go (IfaceTyVar IfLclName
tv)        = IfaceTySubst -> IfLclName -> IfaceType
substIfaceTyVar IfaceTySubst
env IfLclName
tv
    go (IfaceAppTy  IfaceType
t IfaceAppArgs
ts)     = IfaceType -> IfaceAppArgs -> IfaceType
IfaceAppTy  (IfaceType -> IfaceType
go IfaceType
t) (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
substIfaceAppArgs IfaceTySubst
env IfaceAppArgs
ts)
    go (IfaceFunTy FunTyFlag
af IfaceType
w IfaceType
t1 IfaceType
t2)  = FunTyFlag -> IfaceType -> IfaceType -> IfaceType -> IfaceType
IfaceFunTy FunTyFlag
af (IfaceType -> IfaceType
go IfaceType
w) (IfaceType -> IfaceType
go IfaceType
t1) (IfaceType -> IfaceType
go IfaceType
t2)
    go ty :: IfaceType
ty@(IfaceLitTy {})     = IfaceType
ty
    go (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys) = IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp IfaceTyCon
tc (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
substIfaceAppArgs IfaceTySubst
env IfaceAppArgs
tys)
    go (IfaceTupleTy TupleSort
s PromotionFlag
i IfaceAppArgs
tys) = TupleSort -> PromotionFlag -> IfaceAppArgs -> IfaceType
IfaceTupleTy TupleSort
s PromotionFlag
i (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
substIfaceAppArgs IfaceTySubst
env IfaceAppArgs
tys)
    go (IfaceForAllTy {})     = String -> SDoc -> IfaceType
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"substIfaceType" (IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty)
    go (IfaceCastTy IfaceType
ty IfaceCoercion
co)    = IfaceType -> IfaceCoercion -> IfaceType
IfaceCastTy (IfaceType -> IfaceType
go IfaceType
ty) (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)
    go (IfaceCoercionTy IfaceCoercion
co)   = IfaceCoercion -> IfaceType
IfaceCoercionTy (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)

    go_mco :: IfaceMCoercion -> IfaceMCoercion
go_mco IfaceMCoercion
IfaceMRefl    = IfaceMCoercion
IfaceMRefl
    go_mco (IfaceMCo IfaceCoercion
co) = IfaceCoercion -> IfaceMCoercion
IfaceMCo (IfaceCoercion -> IfaceMCoercion)
-> IfaceCoercion -> IfaceMCoercion
forall a b. (a -> b) -> a -> b
$ IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co

    go_co :: IfaceCoercion -> IfaceCoercion
go_co (IfaceReflCo IfaceType
ty)           = IfaceType -> IfaceCoercion
IfaceReflCo (IfaceType -> IfaceType
go IfaceType
ty)
    go_co (IfaceGReflCo Role
r IfaceType
ty IfaceMCoercion
mco)    = Role -> IfaceType -> IfaceMCoercion -> IfaceCoercion
IfaceGReflCo Role
r (IfaceType -> IfaceType
go IfaceType
ty) (IfaceMCoercion -> IfaceMCoercion
go_mco IfaceMCoercion
mco)
    go_co (IfaceFunCo Role
r IfaceCoercion
w IfaceCoercion
c1 IfaceCoercion
c2)     = Role
-> IfaceCoercion -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
IfaceFunCo Role
r (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
w) (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
c1) (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
c2)
    go_co (IfaceTyConAppCo Role
r IfaceTyCon
tc [IfaceCoercion]
cos) = Role -> IfaceTyCon -> [IfaceCoercion] -> IfaceCoercion
IfaceTyConAppCo Role
r IfaceTyCon
tc ([IfaceCoercion] -> [IfaceCoercion]
go_cos [IfaceCoercion]
cos)
    go_co (IfaceAppCo IfaceCoercion
c1 IfaceCoercion
c2)         = IfaceCoercion -> IfaceCoercion -> IfaceCoercion
IfaceAppCo (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
c1) (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
c2)
    go_co (IfaceForAllCo {})         = String -> SDoc -> IfaceCoercion
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"substIfaceCoercion" (IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty)
    go_co (IfaceFreeCoVar TyVar
cv)        = TyVar -> IfaceCoercion
IfaceFreeCoVar TyVar
cv
    go_co (IfaceCoVarCo IfLclName
cv)          = IfLclName -> IfaceCoercion
IfaceCoVarCo IfLclName
cv
    go_co (IfaceHoleCo TyVar
cv)           = TyVar -> IfaceCoercion
IfaceHoleCo TyVar
cv
    go_co (IfaceUnivCo UnivCoProvenance
p Role
r IfaceType
t1 IfaceType
t2 [IfaceCoercion]
ds) = UnivCoProvenance
-> Role
-> IfaceType
-> IfaceType
-> [IfaceCoercion]
-> IfaceCoercion
IfaceUnivCo UnivCoProvenance
p Role
r (IfaceType -> IfaceType
go IfaceType
t1) (IfaceType -> IfaceType
go IfaceType
t2) ([IfaceCoercion] -> [IfaceCoercion]
go_cos [IfaceCoercion]
ds)
    go_co (IfaceSymCo IfaceCoercion
co)            = IfaceCoercion -> IfaceCoercion
IfaceSymCo (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)
    go_co (IfaceTransCo IfaceCoercion
co1 IfaceCoercion
co2)     = IfaceCoercion -> IfaceCoercion -> IfaceCoercion
IfaceTransCo (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co1) (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co2)
    go_co (IfaceSelCo CoSel
n IfaceCoercion
co)          = CoSel -> IfaceCoercion -> IfaceCoercion
IfaceSelCo CoSel
n (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)
    go_co (IfaceLRCo LeftOrRight
lr IfaceCoercion
co)          = LeftOrRight -> IfaceCoercion -> IfaceCoercion
IfaceLRCo LeftOrRight
lr (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)
    go_co (IfaceInstCo IfaceCoercion
c1 IfaceCoercion
c2)        = IfaceCoercion -> IfaceCoercion -> IfaceCoercion
IfaceInstCo (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
c1) (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
c2)
    go_co (IfaceKindCo IfaceCoercion
co)           = IfaceCoercion -> IfaceCoercion
IfaceKindCo (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)
    go_co (IfaceSubCo IfaceCoercion
co)            = IfaceCoercion -> IfaceCoercion
IfaceSubCo (IfaceCoercion -> IfaceCoercion
go_co IfaceCoercion
co)
    go_co (IfaceAxiomCo IfaceAxiomRule
n [IfaceCoercion]
cos)       = IfaceAxiomRule -> [IfaceCoercion] -> IfaceCoercion
IfaceAxiomCo IfaceAxiomRule
n ([IfaceCoercion] -> [IfaceCoercion]
go_cos [IfaceCoercion]
cos)

    go_cos :: [IfaceCoercion] -> [IfaceCoercion]
go_cos = (IfaceCoercion -> IfaceCoercion)
-> [IfaceCoercion] -> [IfaceCoercion]
forall a b. (a -> b) -> [a] -> [b]
map IfaceCoercion -> IfaceCoercion
go_co

substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
substIfaceAppArgs IfaceTySubst
env IfaceAppArgs
args
  = IfaceAppArgs -> IfaceAppArgs
go IfaceAppArgs
args
  where
    go :: IfaceAppArgs -> IfaceAppArgs
go IfaceAppArgs
IA_Nil              = IfaceAppArgs
IA_Nil
    go (IA_Arg IfaceType
ty ForAllTyFlag
arg IfaceAppArgs
tys) = IfaceType -> ForAllTyFlag -> IfaceAppArgs -> IfaceAppArgs
IA_Arg (IfaceTySubst -> IfaceType -> IfaceType
substIfaceType IfaceTySubst
env IfaceType
ty) ForAllTyFlag
arg (IfaceAppArgs -> IfaceAppArgs
go IfaceAppArgs
tys)

substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType
substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType
substIfaceTyVar IfaceTySubst
env IfLclName
tv
  | Just IfaceType
ty <- IfaceTySubst -> FastString -> Maybe IfaceType
forall a. FastStringEnv a -> FastString -> Maybe a
lookupFsEnv IfaceTySubst
env (IfLclName -> FastString
ifLclNameFS IfLclName
tv) = IfaceType
ty
  | Bool
otherwise                     = IfLclName -> IfaceType
IfaceTyVar IfLclName
tv


{-
************************************************************************
*                                                                      *
                Functions over IfaceAppArgs
*                                                                      *
************************************************************************
-}

stripInvisArgs :: PrintExplicitKinds -> IfaceAppArgs -> IfaceAppArgs
stripInvisArgs :: PrintExplicitKinds -> IfaceAppArgs -> IfaceAppArgs
stripInvisArgs (PrintExplicitKinds Bool
True)  IfaceAppArgs
tys = IfaceAppArgs
tys
stripInvisArgs (PrintExplicitKinds Bool
False) IfaceAppArgs
tys = IfaceAppArgs -> IfaceAppArgs
suppress_invis IfaceAppArgs
tys
    where
      suppress_invis :: IfaceAppArgs -> IfaceAppArgs
suppress_invis IfaceAppArgs
c
        = case IfaceAppArgs
c of
            IfaceAppArgs
IA_Nil -> IfaceAppArgs
IA_Nil
            IA_Arg IfaceType
t ForAllTyFlag
argf IfaceAppArgs
ts
              |  ForAllTyFlag -> Bool
isVisibleForAllTyFlag ForAllTyFlag
argf
              -> IfaceType -> ForAllTyFlag -> IfaceAppArgs -> IfaceAppArgs
IA_Arg IfaceType
t ForAllTyFlag
argf (IfaceAppArgs -> IfaceAppArgs) -> IfaceAppArgs -> IfaceAppArgs
forall a b. (a -> b) -> a -> b
$ IfaceAppArgs -> IfaceAppArgs
suppress_invis IfaceAppArgs
ts
              -- Keep recursing through the remainder of the arguments, as it's
              -- possible that there are remaining invisible ones.
              -- See the "In type declarations" section of Note [VarBndrs,
              -- ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep.
              |  Bool
otherwise
              -> IfaceAppArgs -> IfaceAppArgs
suppress_invis IfaceAppArgs
ts

appArgsIfaceTypes :: IfaceAppArgs -> [IfaceType]
appArgsIfaceTypes :: IfaceAppArgs -> [IfaceType]
appArgsIfaceTypes IfaceAppArgs
IA_Nil = []
appArgsIfaceTypes (IA_Arg IfaceType
t ForAllTyFlag
_ IfaceAppArgs
ts) = IfaceType
t IfaceType -> [IfaceType] -> [IfaceType]
forall a. a -> [a] -> [a]
: IfaceAppArgs -> [IfaceType]
appArgsIfaceTypes IfaceAppArgs
ts

appArgsIfaceTypesForAllTyFlags :: IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
appArgsIfaceTypesForAllTyFlags :: IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
appArgsIfaceTypesForAllTyFlags IfaceAppArgs
IA_Nil = []
appArgsIfaceTypesForAllTyFlags (IA_Arg IfaceType
t ForAllTyFlag
a IfaceAppArgs
ts)
                                 = (IfaceType
t, ForAllTyFlag
a) (IfaceType, ForAllTyFlag)
-> [(IfaceType, ForAllTyFlag)] -> [(IfaceType, ForAllTyFlag)]
forall a. a -> [a] -> [a]
: IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
appArgsIfaceTypesForAllTyFlags IfaceAppArgs
ts

ifaceVisAppArgsLength :: IfaceAppArgs -> Int
ifaceVisAppArgsLength :: IfaceAppArgs -> Int
ifaceVisAppArgsLength = Int -> IfaceAppArgs -> Int
forall {t}. Num t => t -> IfaceAppArgs -> t
go Int
0
  where
    go :: t -> IfaceAppArgs -> t
go !t
n IfaceAppArgs
IA_Nil = t
n
    go t
n  (IA_Arg IfaceType
_ ForAllTyFlag
argf IfaceAppArgs
rest)
      | ForAllTyFlag -> Bool
isVisibleForAllTyFlag ForAllTyFlag
argf = t -> IfaceAppArgs -> t
go (t
nt -> t -> t
forall a. Num a => a -> a -> a
+t
1) IfaceAppArgs
rest
      | Bool
otherwise             = t -> IfaceAppArgs -> t
go t
n IfaceAppArgs
rest

ifaceAppArgsLength :: IfaceAppArgs -> Int
ifaceAppArgsLength :: IfaceAppArgs -> Int
ifaceAppArgsLength = Int -> IfaceAppArgs -> Int
forall {t}. Num t => t -> IfaceAppArgs -> t
go Int
0
  where
    go :: t -> IfaceAppArgs -> t
go !t
n IfaceAppArgs
IA_Nil = t
n
    go !t
n (IA_Arg IfaceType
_ ForAllTyFlag
_ IfaceAppArgs
ts) = t -> IfaceAppArgs -> t
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
+ t
1) IfaceAppArgs
ts

{-
Note [Suppressing invisible arguments]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We use the IfaceAppArgs data type to specify which of the arguments to a type
should be displayed when pretty-printing, under the control of
-fprint-explicit-kinds.
See also Type.filterOutInvisibleTypes.
For example, given

    T :: forall k. (k->*) -> k -> *    -- Ordinary kind polymorphism
    'Just :: forall k. k -> 'Maybe k   -- Promoted

we want

    T * Tree Int    prints as    T Tree Int
    'Just *         prints as    Just *

For type constructors (IfaceTyConApp), IfaceAppArgs is a quite natural fit,
since the corresponding Core constructor:

    data Type
      = ...
      | TyConApp TyCon [Type]

Already puts all of its arguments into a list. So when converting a Type to an
IfaceType (see toIfaceAppArgsX in GHC.Core.ToIface), we simply use the kind of
the TyCon (which is cached) to guide the process of converting the argument
Types into an IfaceAppArgs list.

We also want this behavior for IfaceAppTy, since given:

    data Proxy (a :: k)
    f :: forall (t :: forall a. a -> Type). Proxy Type (t Bool True)

We want to print the return type as `Proxy (t True)` without the use of
-fprint-explicit-kinds (#15330). Accomplishing this is trickier than in the
tycon case, because the corresponding Core constructor for IfaceAppTy:

    data Type
      = ...
      | AppTy Type Type

Only stores one argument at a time. Therefore, when converting an AppTy to an
IfaceAppTy (in toIfaceTypeX in GHC.CoreToIface), we:

1. Flatten the chain of AppTys down as much as possible
2. Use typeKind to determine the function Type's kind
3. Use this kind to guide the process of converting the argument Types into an
   IfaceAppArgs list.

By flattening the arguments like this, we obtain two benefits:

(a) We can reuse the same machinery to pretty-print IfaceTyConApp arguments as
    we do IfaceTyApp arguments, which means that we only need to implement the
    logic to filter out invisible arguments once.
(b) Unlike for tycons, finding the kind of a type in general (through typeKind)
    is not a constant-time operation, so by flattening the arguments first, we
    decrease the number of times we have to call typeKind.

Note [Pretty-printing invisible arguments]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note [Suppressing invisible arguments] is all about how to avoid printing
invisible arguments when the -fprint-explicit-kinds flag is disables. Well,
what about when it's enabled? Then we can and should print invisible kind
arguments, and this Note explains how we do it.

As two running examples, consider the following code:

  {-# LANGUAGE PolyKinds #-}
  data T1 a
  data T2 (a :: k)

When displaying these types (with -fprint-explicit-kinds on), we could just
do the following:

  T1 k a
  T2 k a

That certainly gets the job done. But it lacks a crucial piece of information:
is the `k` argument inferred or specified? To communicate this, we use visible
kind application syntax to distinguish the two cases:

  T1 @{k} a
  T2 @k   a

Here, @{k} indicates that `k` is an inferred argument, and @k indicates that
`k` is a specified argument. (See
Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep for
a lengthier explanation on what "inferred" and "specified" mean.)

************************************************************************
*                                                                      *
                Pretty-printing
*                                                                      *
************************************************************************
-}

if_print_coercions :: SDoc  -- ^ if printing coercions
                   -> SDoc  -- ^ otherwise
                   -> SDoc
if_print_coercions :: SDoc -> SDoc -> SDoc
if_print_coercions SDoc
yes SDoc
no
  = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitCoercions ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_co ->
    (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
style ->
    (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
print_co Bool -> Bool -> Bool
|| PprStyle -> Bool
dumpStyle PprStyle
style Bool -> Bool -> Bool
|| Bool
debug
    then SDoc
yes
    else SDoc
no

pprIfaceInfixApp :: PprPrec -> SDoc -> SDoc -> SDoc -> SDoc
pprIfaceInfixApp :: PprPrec -> SDoc -> SDoc -> SDoc -> SDoc
pprIfaceInfixApp PprPrec
ctxt_prec SDoc
pp_tc SDoc
pp_ty1 SDoc
pp_ty2
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
opPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [SDoc
pp_ty1, SDoc
pp_tc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
pp_ty2]

pprIfacePrefixApp :: PprPrec -> SDoc -> [SDoc] -> SDoc
pprIfacePrefixApp :: PprPrec -> SDoc -> [SDoc] -> SDoc
pprIfacePrefixApp PprPrec
ctxt_prec SDoc
pp_fun [SDoc]
pp_tys
  | [SDoc] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SDoc]
pp_tys = SDoc
pp_fun
  | Bool
otherwise   = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
appPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
                  SDoc -> Int -> SDoc -> SDoc
hang SDoc
pp_fun Int
2 ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [SDoc]
pp_tys)

isIfaceRhoType :: IfaceType -> Bool
isIfaceRhoType :: IfaceType -> Bool
isIfaceRhoType (IfaceForAllTy IfaceForAllBndr
_ IfaceType
_)   = Bool
False
isIfaceRhoType (IfaceFunTy FunTyFlag
af IfaceType
_ IfaceType
_ IfaceType
_) = FunTyFlag -> Bool
isVisibleFunArg FunTyFlag
af
isIfaceRhoType IfaceType
_ = Bool
True

-- ----------------------------- Printing binders ------------------------------------

instance Outputable IfaceBndr where
    ppr :: IfaceBndr -> SDoc
ppr (IfaceIdBndr IfaceIdBndr
bndr) = IfaceIdBndr -> SDoc
pprIfaceIdBndr IfaceIdBndr
bndr
    ppr (IfaceTvBndr IfaceTvBndr
bndr) = Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
pprIfaceTvBndr IfaceTvBndr
bndr (Bool -> SuppressBndrSig
SuppressBndrSig Bool
False)
                                                             (Bool -> UseBndrParens
UseBndrParens Bool
False)

pprIfaceBndrs :: [IfaceBndr] -> SDoc
pprIfaceBndrs :: [IfaceBndr] -> SDoc
pprIfaceBndrs [IfaceBndr]
bs = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((IfaceBndr -> SDoc) -> [IfaceBndr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map IfaceBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr [IfaceBndr]
bs)

pprIfaceLamBndr :: IfaceLamBndr -> SDoc
pprIfaceLamBndr :: IfaceLamBndr -> SDoc
pprIfaceLamBndr (IfaceBndr
b, IfaceOneShot
IfaceNoOneShot) = IfaceBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceBndr
b
pprIfaceLamBndr (IfaceBndr
b, IfaceOneShot
IfaceOneShot)   = IfaceBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceBndr
b SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"[OneShot]"

pprIfaceIdBndr :: IfaceIdBndr -> SDoc
pprIfaceIdBndr :: IfaceIdBndr -> SDoc
pprIfaceIdBndr (IfaceType
w, IfLclName
name, IfaceType
ty) = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
brackets (IfaceType -> SDoc
ppr_ty_nested IfaceType
w) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceType -> SDoc
ppr_ty_nested IfaceType
ty)

{- Note [Suppressing binder signatures]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When printing the binders in a 'forall', we want to keep the kind annotations:

    forall (a :: k). blah
              ^^^^
              good

On the other hand, when we print the binders of a data declaration in :info,
the kind information would be redundant due to the standalone kind signature:

   type F :: Symbol -> Type
   type F (s :: Symbol) = blah
             ^^^^^^^^^
             redundant

Here we'd like to omit the kind annotation:

   type F :: Symbol -> Type
   type F s = blah

Note [Printing type abbreviations]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Normally, we pretty-print
   `TYPE       'LiftedRep` as `Type` (or `*`)
   `CONSTRAINT 'LiftedRep` as `Constraint`
   `FUN 'Many`             as `(->)`
This way, error messages don't refer to representation polymorphism
or linearity if it is not necessary.  Normally we'd would represent
these types using their synonyms (see GHC.Core.Type
Note [Using synonyms to compress types]), but in the :kind! GHCi
command we specifically expand synonyms (see GHC.Tc.Module.tcRnExpr).
So here in the pretty-printing we effectively collapse back Type
and Constraint to their synonym forms.  A bit confusing!

However, when printing the definition of Type, Constraint or (->) with :info,
this would give confusing output: `type (->) = (->)` (#18594).
Solution: detect when we are in :info and disable displaying the synonym
with the SDoc option sdocPrintTypeAbbreviations.
If you are creating a similar synonym, make sure it is listed in pprIfaceDecl,
see reference to this Note.

If there will be a need, in the future we could expose it as a flag
-fprint-type-abbreviations or even three separate flags controlling
TYPE 'LiftedRep, CONSTRAINT 'LiftedRep and FUN 'Many.
-}

-- | Do we want to suppress kind annotations on binders?
-- See Note [Suppressing binder signatures]
newtype SuppressBndrSig = SuppressBndrSig Bool

newtype UseBndrParens      = UseBndrParens Bool
newtype PrintExplicitKinds = PrintExplicitKinds Bool

pprIfaceTvBndr :: IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
pprIfaceTvBndr :: IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
pprIfaceTvBndr (IfLclName
tv, IfaceType
ki) (SuppressBndrSig Bool
suppress_sig) (UseBndrParens Bool
use_parens)
  | Bool
suppress_sig             = IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
tv
  | IfaceType -> Bool
isIfaceLiftedTypeKind IfaceType
ki = IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
tv
  | Bool
otherwise                = SDoc -> SDoc
maybe_parens (IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceType -> SDoc
ppr_ty_nested IfaceType
ki)
  where
    maybe_parens :: SDoc -> SDoc
maybe_parens | Bool
use_parens = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens
                 | Bool
otherwise  = SDoc -> SDoc
forall a. a -> a
id

pprIfaceTyConBinders :: SuppressBndrSig -> [IfaceTyConBinder] -> SDoc
pprIfaceTyConBinders :: SuppressBndrSig -> [IfaceTyConBinder] -> SDoc
pprIfaceTyConBinders SuppressBndrSig
suppress_sig = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ([SDoc] -> SDoc)
-> ([IfaceTyConBinder] -> [SDoc]) -> [IfaceTyConBinder] -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IfaceTyConBinder -> SDoc) -> [IfaceTyConBinder] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map IfaceTyConBinder -> SDoc
go
  where
    go :: IfaceTyConBinder -> SDoc
    go :: IfaceTyConBinder -> SDoc
go (Bndr (IfaceIdBndr IfaceIdBndr
bndr) TyConBndrVis
_) = IfaceIdBndr -> SDoc
pprIfaceIdBndr IfaceIdBndr
bndr
    go (Bndr (IfaceTvBndr IfaceTvBndr
bndr) TyConBndrVis
vis) =
      -- See Note [Pretty-printing invisible arguments]
      case TyConBndrVis
vis of
        TyConBndrVis
AnonTCB            -> UseBndrParens -> SDoc
ppr_bndr (Bool -> UseBndrParens
UseBndrParens Bool
True)
        NamedTCB ForAllTyFlag
Required  -> UseBndrParens -> SDoc
ppr_bndr (Bool -> UseBndrParens
UseBndrParens Bool
True)
        NamedTCB ForAllTyFlag
Specified -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> UseBndrParens -> SDoc
ppr_bndr (Bool -> UseBndrParens
UseBndrParens Bool
True)
        NamedTCB ForAllTyFlag
Inferred  -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (UseBndrParens -> SDoc
ppr_bndr (Bool -> UseBndrParens
UseBndrParens Bool
False))
      where
        ppr_bndr :: UseBndrParens -> SDoc
ppr_bndr = IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
pprIfaceTvBndr IfaceTvBndr
bndr SuppressBndrSig
suppress_sig

instance Binary IfaceBndr where
    put_ :: WriteBinHandle -> IfaceBndr -> IO ()
put_ WriteBinHandle
bh (IfaceIdBndr IfaceIdBndr
aa) = do
            WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
0
            WriteBinHandle -> IfaceIdBndr -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceIdBndr
aa
    put_ WriteBinHandle
bh (IfaceTvBndr IfaceTvBndr
ab) = do
            WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1
            WriteBinHandle -> IfaceTvBndr -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceTvBndr
ab
    get :: ReadBinHandle -> IO IfaceBndr
get ReadBinHandle
bh = do
            h <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
            case h of
              Word8
0 -> do aa <- ReadBinHandle -> IO IfaceIdBndr
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      return (IfaceIdBndr aa)
              Word8
_ -> do ab <- ReadBinHandle -> IO IfaceTvBndr
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      return (IfaceTvBndr ab)

instance Binary IfaceOneShot where
    put_ :: WriteBinHandle -> IfaceOneShot -> IO ()
put_ WriteBinHandle
bh IfaceOneShot
IfaceNoOneShot =
            WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
0
    put_ WriteBinHandle
bh IfaceOneShot
IfaceOneShot =
            WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1
    get :: ReadBinHandle -> IO IfaceOneShot
get ReadBinHandle
bh = do
            h <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
            case h of
              Word8
0 -> IfaceOneShot -> IO IfaceOneShot
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IfaceOneShot
IfaceNoOneShot
              Word8
_ -> IfaceOneShot -> IO IfaceOneShot
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IfaceOneShot
IfaceOneShot

-- ----------------------------- Printing IfaceType ------------------------------------

---------------------------------
instance Outputable IfaceType where
  ppr :: IfaceType -> SDoc
ppr IfaceType
ty = IfaceType -> SDoc
pprIfaceType IfaceType
ty

-- The purpose of 'ppr_ty_nested' is to distinguish calls that should not
-- trigger 'hideNonStandardTypes', see Note [Defaulting RuntimeRep variables]
-- wrinkle (W2).
pprIfaceType, pprParendIfaceType, ppr_ty_nested :: IfaceType -> SDoc
pprIfaceType :: IfaceType -> SDoc
pprIfaceType       = PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
topPrec
pprParendIfaceType :: IfaceType -> SDoc
pprParendIfaceType = PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
appPrec
ppr_ty_nested :: IfaceType -> SDoc
ppr_ty_nested = PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
topPrec

pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc
-- We still need `hideNonStandardTypes`, since the `pprPrecIfaceType` may be
-- called from other places, besides `:type` and `:info`.
pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
prec IfaceType
ty =
  (IfaceType -> SDoc) -> IfaceType -> SDoc
hideNonStandardTypes (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
prec) IfaceType
ty

pprTypeArrow :: FunTyFlag -> IfaceMult -> SDoc
pprTypeArrow :: FunTyFlag -> IfaceType -> SDoc
pprTypeArrow FunTyFlag
af IfaceType
mult
  = (IfaceType -> Maybe IfaceTyCon, PprPrec -> IfaceType -> SDoc)
-> FunTyFlag -> IfaceType -> SDoc
forall a.
(a -> Maybe IfaceTyCon, PprPrec -> a -> SDoc)
-> FunTyFlag -> a -> SDoc
pprArrow (IfaceType -> Maybe IfaceTyCon
mb_conc, PprPrec -> IfaceType -> SDoc
pprPrecIfaceType) FunTyFlag
af IfaceType
mult
  where
    mb_conc :: IfaceType -> Maybe IfaceTyCon
mb_conc (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
_) = IfaceTyCon -> Maybe IfaceTyCon
forall a. a -> Maybe a
Just IfaceTyCon
tc
    mb_conc IfaceType
_                    = Maybe IfaceTyCon
forall a. Maybe a
Nothing

pprArrow :: (a -> Maybe IfaceTyCon, PprPrec -> a -> SDoc)
         -> FunTyFlag -> a -> SDoc
-- Prints a thin arrow (->) with its multiplicity
-- Used for both FunTy and FunCo, hence higher order arguments
pprArrow :: forall a.
(a -> Maybe IfaceTyCon, PprPrec -> a -> SDoc)
-> FunTyFlag -> a -> SDoc
pprArrow (a -> Maybe IfaceTyCon
mb_conc, PprPrec -> a -> SDoc
ppr_mult) FunTyFlag
af a
mult
  | FunTyFlag -> Bool
isFUNArg FunTyFlag
af
  = case a -> Maybe IfaceTyCon
mb_conc a
mult of
      Just IfaceTyCon
tc | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
manyDataConKey -> SDoc
arrow
              | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
oneDataConKey  -> SDoc
lollipop
      Maybe IfaceTyCon
_ -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"%" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> PprPrec -> a -> SDoc
ppr_mult PprPrec
appPrec a
mult SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow
  | Bool
otherwise
  = TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr (FunTyFlag -> TyCon
funTyFlagTyCon FunTyFlag
af)

ppr_ty :: PprPrec -> IfaceType -> SDoc
ppr_ty :: PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
ctxt_prec IfaceType
ty
  | Bool -> Bool
not (IfaceType -> Bool
isIfaceRhoType IfaceType
ty)             = ShowForAllFlag -> PprPrec -> IfaceType -> SDoc
ppr_sigma ShowForAllFlag
ShowForAllMust PprPrec
ctxt_prec IfaceType
ty
ppr_ty PprPrec
_         (IfaceForAllTy {})     = String -> SDoc
forall a. HasCallStack => String -> a
panic String
"ppr_ty"  -- Covered by not.isIfaceRhoType
ppr_ty PprPrec
_         (IfaceFreeTyVar TyVar
tyvar) = TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVar
tyvar  -- This is the main reason for IfaceFreeTyVar!
ppr_ty PprPrec
_         (IfaceTyVar IfLclName
tyvar)     = IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
tyvar  -- See Note [Free TyVars and CoVars in IfaceType]
ppr_ty PprPrec
ctxt_prec (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys) = PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprTyTcApp PprPrec
ctxt_prec IfaceTyCon
tc IfaceAppArgs
tys
ppr_ty PprPrec
ctxt_prec (IfaceTupleTy TupleSort
i PromotionFlag
p IfaceAppArgs
tys) = PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple PprPrec
ctxt_prec TupleSort
i PromotionFlag
p IfaceAppArgs
tys -- always fully saturated
ppr_ty PprPrec
_         (IfaceLitTy IfaceTyLit
n)         = IfaceTyLit -> SDoc
pprIfaceTyLit IfaceTyLit
n

        -- Function types
ppr_ty PprPrec
ctxt_prec ty :: IfaceType
ty@(IfaceFunTy FunTyFlag
af IfaceType
w IfaceType
ty1 IfaceType
ty2)  -- Should be a visible argument
  = Bool -> SDoc -> SDoc -> SDoc
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (FunTyFlag -> Bool
isVisibleFunArg FunTyFlag
af) (IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$  -- Ensured by isIfaceRhoType above
    -- We want to print a chain of arrows in a column
    --     type1
    --     -> type2
    --     -> type3
    PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
funPrec IfaceType
ty1, [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep (IfaceType -> IfaceType -> [SDoc]
ppr_fun_tail IfaceType
w IfaceType
ty2)]
  where
    ppr_fun_tail :: IfaceType -> IfaceType -> [SDoc]
ppr_fun_tail IfaceType
wthis (IfaceFunTy FunTyFlag
af IfaceType
wnext IfaceType
ty1 IfaceType
ty2)
      | FunTyFlag -> Bool
isVisibleFunArg FunTyFlag
af
      = (FunTyFlag -> IfaceType -> SDoc
pprTypeArrow FunTyFlag
af IfaceType
wthis SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
funPrec IfaceType
ty1) SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: IfaceType -> IfaceType -> [SDoc]
ppr_fun_tail IfaceType
wnext IfaceType
ty2
    ppr_fun_tail IfaceType
wthis IfaceType
other_ty
      = [FunTyFlag -> IfaceType -> SDoc
pprTypeArrow FunTyFlag
af IfaceType
wthis SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceType -> SDoc
ppr_ty_nested IfaceType
other_ty]

ppr_ty PprPrec
ctxt_prec (IfaceAppTy IfaceType
t IfaceAppArgs
ts)
  = SDoc -> SDoc -> SDoc
if_print_coercions
      SDoc
ppr_app_ty
      SDoc
ppr_app_ty_no_casts
  where
    ppr_app_ty :: SDoc
ppr_app_ty =
        (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitKinds ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_kinds ->
        let tys_wo_kinds :: [(IfaceType, ForAllTyFlag)]
tys_wo_kinds = IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
appArgsIfaceTypesForAllTyFlags (IfaceAppArgs -> [(IfaceType, ForAllTyFlag)])
-> IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
forall a b. (a -> b) -> a -> b
$ PrintExplicitKinds -> IfaceAppArgs -> IfaceAppArgs
stripInvisArgs
                              (Bool -> PrintExplicitKinds
PrintExplicitKinds Bool
print_kinds) IfaceAppArgs
ts
        in PprPrec -> SDoc -> [SDoc] -> SDoc
pprIfacePrefixApp PprPrec
ctxt_prec
                             (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
funPrec IfaceType
t)
                             (((IfaceType, ForAllTyFlag) -> SDoc)
-> [(IfaceType, ForAllTyFlag)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc
ppr_app_arg PprPrec
appPrec) [(IfaceType, ForAllTyFlag)]
tys_wo_kinds)


    -- Strip any casts from the head of the application
    ppr_app_ty_no_casts :: SDoc
ppr_app_ty_no_casts =
        case IfaceType
t of
          IfaceCastTy IfaceType
head IfaceCoercion
_ -> PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
ctxt_prec (IfaceType -> IfaceAppArgs -> IfaceType
mk_app_tys IfaceType
head IfaceAppArgs
ts)
          IfaceType
_                  -> SDoc
ppr_app_ty

    mk_app_tys :: IfaceType -> IfaceAppArgs -> IfaceType
    mk_app_tys :: IfaceType -> IfaceAppArgs -> IfaceType
mk_app_tys (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys1) IfaceAppArgs
tys2 =
        IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp IfaceTyCon
tc (IfaceAppArgs
tys1 IfaceAppArgs -> IfaceAppArgs -> IfaceAppArgs
forall a. Monoid a => a -> a -> a
`mappend` IfaceAppArgs
tys2)
    mk_app_tys IfaceType
t1 IfaceAppArgs
tys2 = IfaceType -> IfaceAppArgs -> IfaceType
IfaceAppTy IfaceType
t1 IfaceAppArgs
tys2

ppr_ty PprPrec
ctxt_prec (IfaceCastTy IfaceType
ty IfaceCoercion
co)
  = SDoc -> SDoc -> SDoc
if_print_coercions
      (SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
topPrec IfaceType
ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"|>" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceCoercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceCoercion
co))
      (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
ctxt_prec IfaceType
ty)

ppr_ty PprPrec
ctxt_prec (IfaceCoercionTy IfaceCoercion
co)
  = SDoc -> SDoc -> SDoc
if_print_coercions
      (PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
ctxt_prec IfaceCoercion
co)
      (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"<>")

{- Note [Defaulting RuntimeRep variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RuntimeRep variables are considered by many (most?) users to be little
more than syntactic noise. When the notion was introduced there was a
significant and understandable push-back from those with pedagogy in
mind, which argued that RuntimeRep variables would throw a wrench into
nearly any teach approach since they appear in even the lowly ($)
function's type,

    ($) :: forall (w :: RuntimeRep) a (b :: TYPE w). (a -> b) -> a -> b

which is significantly less readable than its non RuntimeRep-polymorphic type of

    ($) :: (a -> b) -> a -> b

Moreover, unboxed types don't appear all that often in run-of-the-mill
Haskell programs, so it makes little sense to make all users pay this
syntactic overhead.

For this reason it was decided that we would hide RuntimeRep variables
for now (see #11549). We do this right in the pretty-printer, by pre-processing
the type we are about to print, to default any type variables of kind RuntimeRep
that are bound by toplevel invisible quantification to LiftedRep.
Likewise, we default Multiplicity variables to Many and Levity variables to
Lifted.

This is done in a pass right before pretty-printing
(defaultIfaceTyVarsOfKind, controlled by
-fprint-explicit-runtime-reps and -XLinearTypes)

This applies to /quantified/ variables like 'w' above.  What about
variables that are /free/ in the type being printed, which certainly
happens in error messages.  Suppose (#16074, #19361) we are reporting a
mismatch between skolems
          (a :: RuntimeRep) ~ (b :: RuntimeRep)
        or
          (m :: Multiplicity) ~ Many
We certainly don't want to say "Can't match LiftedRep with LiftedRep" or
"Can't match Many with Many"!

But if we are printing the type
    (forall (a :: TYPE r). blah)
we do want to turn that (free) r into LiftedRep, so it prints as
    (forall a. blah)

We use isMetaTyVar to distinguish between those two situations:
metavariables are converted, skolem variables are not.

There's one exception though: TyVarTv metavariables should not be defaulted,
as they appear during kind-checking of "newtype T :: TYPE r where..."
(test T18357a). Therefore, we additionally test for isTyConableTyVar.

Wrinkles:

(W1) The loop 'go' in 'defaultIfaceTyVarsOfKind' passes a Bool flag, 'rank1',
     around that indicates whether we haven't yet descended into the arguments
     of a function type.
     This is used to decide whether newly bound variables are eligible for
     defaulting – we do not want contravariant foralls to be defaulted because
     that would result in an incorrect, rather than specialized, type.
     For example:
       ∀ p (r1 :: RuntimeRep) . (∀ (r2 :: RuntimeRep) . p r2) -> p r1
     We want to default 'r1', but not 'r2'.
     When examining the first forall, 'rank1' is True.
     The toplevel function type is matched as IfaceFunTy, where we recurse into
     'go' by passing False for 'rank1'.
     The forall in the first argument then skips adding a substitution for 'r2'.

(W2) 'defaultIfaceTyVarsOfKind' ought to be called only once when printing a
     type.
     A few components of the printing machinery used to invoke 'ppr' on types
     nested in secondary structures like IfaceBndr, which would repeat the
     defaulting process, but treating the type as if it were top-level, causing
     unwanted defaulting.
     In order to prevent future developers from using 'ppr' again or being
     confused that @ppr_ty topPrec@ is used, we introduced a marker function,
     'ppr_ty_nested'.
-}

-- | Default 'RuntimeRep' variables to 'LiftedRep',
--   'Levity' variables to 'Lifted', and 'Multiplicity'
--   variables to 'Many'. For example:
--
-- @
-- ($) :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r).
--        (a -> b) -> a -> b
-- Just :: forall (k :: Multiplicity) a. a % k -> Maybe a
-- @
--
-- turns in to,
--
-- @ ($) :: forall a (b :: *). (a -> b) -> a -> b @
-- @ Just :: forall a . a -> Maybe a @
--
-- We do this to prevent RuntimeRep, Levity and Multiplicity variables from
-- incurring a significant syntactic overhead in otherwise simple
-- type signatures (e.g. ($)). See Note [Defaulting RuntimeRep variables]
-- and #11549 for further discussion.
defaultIfaceTyVarsOfKind :: Bool -- ^ default 'RuntimeRep'/'Levity' variables?
                         -> Bool -- ^ default 'Multiplicity' variables?
                         -> IfaceType -> IfaceType
defaultIfaceTyVarsOfKind :: Bool -> Bool -> IfaceType -> IfaceType
defaultIfaceTyVarsOfKind Bool
def_rep Bool
def_mult IfaceType
ty = IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
forall a. FastStringEnv a
emptyFsEnv Bool
True IfaceType
ty
  where
    go :: FastStringEnv IfaceType -- Set of enclosing forall-ed RuntimeRep/Levity/Multiplicity variables
       -> Bool -- Are we in a toplevel forall, where defaulting is allowed?
       -> IfaceType
       -> IfaceType
    go :: IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
True (IfaceForAllTy (Bndr (IfaceTvBndr (IfLclName
var, IfaceType
var_kind)) ForAllTyFlag
argf) IfaceType
ty)
     | ForAllTyFlag -> Bool
isInvisibleForAllTyFlag ForAllTyFlag
argf  -- Don't default *visible* quantification
                                     -- or we get the mess in #13963
     , Just IfaceType
substituted_ty <- IfaceType -> Maybe IfaceType
check_substitution IfaceType
var_kind
      = let subs' :: IfaceTySubst
subs' = IfaceTySubst -> FastString -> IfaceType -> IfaceTySubst
forall a. FastStringEnv a -> FastString -> a -> FastStringEnv a
extendFsEnv IfaceTySubst
subs (IfLclName -> FastString
ifLclNameFS IfLclName
var) IfaceType
substituted_ty
            -- Record that we should replace it with LiftedRep/Lifted/Many,
            -- and recurse, discarding the forall
        in IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs' Bool
True IfaceType
ty

    go IfaceTySubst
subs Bool
rank1 (IfaceForAllTy IfaceForAllBndr
bndr IfaceType
ty)
      = IfaceForAllBndr -> IfaceType -> IfaceType
IfaceForAllTy (IfaceTySubst -> IfaceForAllBndr -> IfaceForAllBndr
go_ifacebndr IfaceTySubst
subs IfaceForAllBndr
bndr) (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
rank1 IfaceType
ty)

    go IfaceTySubst
subs Bool
_ ty :: IfaceType
ty@(IfaceTyVar IfLclName
tv) = case IfaceTySubst -> FastString -> Maybe IfaceType
forall a. FastStringEnv a -> FastString -> Maybe a
lookupFsEnv IfaceTySubst
subs (IfLclName -> FastString
ifLclNameFS IfLclName
tv) of
      Just IfaceType
s -> IfaceType
s
      Maybe IfaceType
Nothing -> IfaceType
ty

    go IfaceTySubst
_ Bool
_ ty :: IfaceType
ty@(IfaceFreeTyVar TyVar
tv)
      -- See Note [Defaulting RuntimeRep variables], about free vars
      | Bool
def_rep
      , Type -> Bool
GHC.Core.Type.isRuntimeRepTy (TyVar -> Type
tyVarKind TyVar
tv)
      , TyVar -> Bool
isMetaTyVar TyVar
tv
      , TyVar -> Bool
isTyConableTyVar TyVar
tv
      = IfaceType
liftedRep_ty
      | Bool
def_rep
      , Type -> Bool
GHC.Core.Type.isLevityTy (TyVar -> Type
tyVarKind TyVar
tv)
      , TyVar -> Bool
isMetaTyVar TyVar
tv
      , TyVar -> Bool
isTyConableTyVar TyVar
tv
      = IfaceType
lifted_ty
      | Bool
def_mult
      , Type -> Bool
GHC.Core.Type.isMultiplicityTy (TyVar -> Type
tyVarKind TyVar
tv)
      , TyVar -> Bool
isMetaTyVar TyVar
tv
      , TyVar -> Bool
isTyConableTyVar TyVar
tv
      = IfaceType
many_ty
      | Bool
otherwise
      = IfaceType
ty

    go IfaceTySubst
subs Bool
_ (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tc_args)
      = IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp IfaceTyCon
tc (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
go_args IfaceTySubst
subs IfaceAppArgs
tc_args)

    go IfaceTySubst
subs Bool
_ (IfaceTupleTy TupleSort
sort PromotionFlag
is_prom IfaceAppArgs
tc_args)
      = TupleSort -> PromotionFlag -> IfaceAppArgs -> IfaceType
IfaceTupleTy TupleSort
sort PromotionFlag
is_prom (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
go_args IfaceTySubst
subs IfaceAppArgs
tc_args)

    go IfaceTySubst
subs Bool
rank1 (IfaceFunTy FunTyFlag
af IfaceType
w IfaceType
arg IfaceType
res)
      = FunTyFlag -> IfaceType -> IfaceType -> IfaceType -> IfaceType
IfaceFunTy FunTyFlag
af (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
False IfaceType
w) (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
False IfaceType
arg) (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
rank1 IfaceType
res)

    go IfaceTySubst
subs Bool
_ (IfaceAppTy IfaceType
t IfaceAppArgs
ts)
      = IfaceType -> IfaceAppArgs -> IfaceType
IfaceAppTy (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
False IfaceType
t) (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
go_args IfaceTySubst
subs IfaceAppArgs
ts)

    go IfaceTySubst
subs Bool
rank1 (IfaceCastTy IfaceType
x IfaceCoercion
co)
      = IfaceType -> IfaceCoercion -> IfaceType
IfaceCastTy (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
rank1 IfaceType
x) IfaceCoercion
co

    go IfaceTySubst
_ Bool
_ ty :: IfaceType
ty@(IfaceLitTy {}) = IfaceType
ty
    go IfaceTySubst
_ Bool
_ ty :: IfaceType
ty@(IfaceCoercionTy {}) = IfaceType
ty

    go_ifacebndr :: FastStringEnv IfaceType -> IfaceForAllBndr -> IfaceForAllBndr
    go_ifacebndr :: IfaceTySubst -> IfaceForAllBndr -> IfaceForAllBndr
go_ifacebndr IfaceTySubst
subs (Bndr (IfaceIdBndr (IfaceType
w, IfLclName
n, IfaceType
t)) ForAllTyFlag
argf)
      = IfaceBndr -> ForAllTyFlag -> IfaceForAllBndr
forall var argf. var -> argf -> VarBndr var argf
Bndr (IfaceIdBndr -> IfaceBndr
IfaceIdBndr (IfaceType
w, IfLclName
n, IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
False IfaceType
t)) ForAllTyFlag
argf
    go_ifacebndr IfaceTySubst
subs (Bndr (IfaceTvBndr (IfLclName
n, IfaceType
t)) ForAllTyFlag
argf)
      = IfaceBndr -> ForAllTyFlag -> IfaceForAllBndr
forall var argf. var -> argf -> VarBndr var argf
Bndr (IfaceTvBndr -> IfaceBndr
IfaceTvBndr (IfLclName
n, IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
False IfaceType
t)) ForAllTyFlag
argf

    go_args :: FastStringEnv IfaceType -> IfaceAppArgs -> IfaceAppArgs
    go_args :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
go_args IfaceTySubst
_ IfaceAppArgs
IA_Nil = IfaceAppArgs
IA_Nil
    go_args IfaceTySubst
subs (IA_Arg IfaceType
ty ForAllTyFlag
argf IfaceAppArgs
args)
      = IfaceType -> ForAllTyFlag -> IfaceAppArgs -> IfaceAppArgs
IA_Arg (IfaceTySubst -> Bool -> IfaceType -> IfaceType
go IfaceTySubst
subs Bool
False IfaceType
ty) ForAllTyFlag
argf (IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
go_args IfaceTySubst
subs IfaceAppArgs
args)

    check_substitution :: IfaceType -> Maybe IfaceType
    check_substitution :: IfaceType -> Maybe IfaceType
check_substitution (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
_)
        | Bool
def_rep
        , IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
runtimeRepTyConKey
        = IfaceType -> Maybe IfaceType
forall a. a -> Maybe a
Just IfaceType
liftedRep_ty
        | Bool
def_rep
        , IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
levityTyConKey
        = IfaceType -> Maybe IfaceType
forall a. a -> Maybe a
Just IfaceType
lifted_ty
        | Bool
def_mult
        , IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
multiplicityTyConKey
        = IfaceType -> Maybe IfaceType
forall a. a -> Maybe a
Just IfaceType
many_ty
    check_substitution IfaceType
_ = Maybe IfaceType
forall a. Maybe a
Nothing

-- | The type ('BoxedRep 'Lifted), also known as LiftedRep.
liftedRep_ty :: IfaceType
liftedRep_ty :: IfaceType
liftedRep_ty =
  IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp IfaceTyCon
liftedRep IfaceAppArgs
IA_Nil
  where
    liftedRep :: IfaceTyCon
    liftedRep :: IfaceTyCon
liftedRep = IfExtName -> IfaceTyConInfo -> IfaceTyCon
IfaceTyCon IfExtName
tc_name (PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo PromotionFlag
NotPromoted IfaceTyConSort
IfaceNormalTyCon)
      where tc_name :: IfExtName
tc_name = TyCon -> IfExtName
forall a. NamedThing a => a -> IfExtName
getName TyCon
liftedRepTyCon

-- | The type 'Lifted :: Levity'.
lifted_ty :: IfaceType
lifted_ty :: IfaceType
lifted_ty =
    IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp (IfExtName -> IfaceTyConInfo -> IfaceTyCon
IfaceTyCon IfExtName
dc_name (PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo PromotionFlag
IsPromoted IfaceTyConSort
IfaceNormalTyCon))
                  IfaceAppArgs
IA_Nil
  where dc_name :: IfExtName
dc_name = TyCon -> IfExtName
forall a. NamedThing a => a -> IfExtName
getName TyCon
liftedDataConTyCon

-- | The type 'Many :: Multiplicity'.
many_ty :: IfaceType
many_ty :: IfaceType
many_ty = IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp (IfExtName -> IfaceTyConInfo -> IfaceTyCon
IfaceTyCon IfExtName
dc_name (PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo PromotionFlag
IsPromoted IfaceTyConSort
IfaceNormalTyCon))
                        IfaceAppArgs
IA_Nil
  where dc_name :: IfExtName
dc_name = TyCon -> IfExtName
forall a. NamedThing a => a -> IfExtName
getName TyCon
manyDataConTyCon

hideNonStandardTypes :: (IfaceType -> SDoc) -> IfaceType -> SDoc
hideNonStandardTypes :: (IfaceType -> SDoc) -> IfaceType -> SDoc
hideNonStandardTypes IfaceType -> SDoc
f IfaceType
ty
  = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitRuntimeReps ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
printExplicitRuntimeReps ->
    (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocLinearTypes ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
linearTypes ->
    (PprStyle -> SDoc) -> SDoc
getPprStyle      ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
sty    ->
    let def_rep :: Bool
def_rep  = Bool -> Bool
not Bool
printExplicitRuntimeReps
        def_mult :: Bool
def_mult = Bool -> Bool
not Bool
linearTypes
    in if PprStyle -> Bool
userStyle PprStyle
sty
       then IfaceType -> SDoc
f (Bool -> Bool -> IfaceType -> IfaceType
defaultIfaceTyVarsOfKind Bool
def_rep Bool
def_mult IfaceType
ty)
       else IfaceType -> SDoc
f IfaceType
ty

instance Outputable IfaceAppArgs where
  ppr :: IfaceAppArgs -> SDoc
ppr IfaceAppArgs
tca = IfaceAppArgs -> SDoc
pprIfaceAppArgs IfaceAppArgs
tca

pprIfaceAppArgs, pprParendIfaceAppArgs :: IfaceAppArgs -> SDoc
pprIfaceAppArgs :: IfaceAppArgs -> SDoc
pprIfaceAppArgs  = PprPrec -> IfaceAppArgs -> SDoc
ppr_app_args PprPrec
topPrec
pprParendIfaceAppArgs :: IfaceAppArgs -> SDoc
pprParendIfaceAppArgs = PprPrec -> IfaceAppArgs -> SDoc
ppr_app_args PprPrec
appPrec

ppr_app_args :: PprPrec -> IfaceAppArgs -> SDoc
ppr_app_args :: PprPrec -> IfaceAppArgs -> SDoc
ppr_app_args PprPrec
ctx_prec = IfaceAppArgs -> SDoc
go
  where
    go :: IfaceAppArgs -> SDoc
    go :: IfaceAppArgs -> SDoc
go IfaceAppArgs
IA_Nil             = SDoc
forall doc. IsOutput doc => doc
empty
    go (IA_Arg IfaceType
t ForAllTyFlag
argf IfaceAppArgs
ts) = PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc
ppr_app_arg PprPrec
ctx_prec (IfaceType
t, ForAllTyFlag
argf) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceAppArgs -> SDoc
go IfaceAppArgs
ts

-- See Note [Pretty-printing invisible arguments]
ppr_app_arg :: PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc
ppr_app_arg :: PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc
ppr_app_arg PprPrec
ctx_prec (IfaceType
t, ForAllTyFlag
argf) =
  (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitKinds ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_kinds ->
  case ForAllTyFlag
argf of
       ForAllTyFlag
Required  -> PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
ctx_prec IfaceType
t
       ForAllTyFlag
Specified |  Bool
print_kinds
                 -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
appPrec IfaceType
t
       ForAllTyFlag
Inferred  |  Bool
print_kinds
                 -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (IfaceType -> SDoc
ppr_ty_nested IfaceType
t)
       ForAllTyFlag
_         -> SDoc
forall doc. IsOutput doc => doc
empty

-------------------
pprIfaceForAllPart :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
pprIfaceForAllPart :: [IfaceForAllBndr] -> [IfaceType] -> SDoc -> SDoc
pprIfaceForAllPart [IfaceForAllBndr]
tvs [IfaceType]
ctxt SDoc
sdoc
  = ShowForAllFlag -> [IfaceForAllBndr] -> [IfaceType] -> SDoc -> SDoc
ppr_iface_forall_part ShowForAllFlag
ShowForAllWhen [IfaceForAllBndr]
tvs [IfaceType]
ctxt SDoc
sdoc

-- | Like 'pprIfaceForAllPart', but always uses an explicit @forall@.
pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfaceType] -> SDoc -> SDoc
pprIfaceForAllPartMust [IfaceForAllBndr]
tvs [IfaceType]
ctxt SDoc
sdoc
  = ShowForAllFlag -> [IfaceForAllBndr] -> [IfaceType] -> SDoc -> SDoc
ppr_iface_forall_part ShowForAllFlag
ShowForAllMust [IfaceForAllBndr]
tvs [IfaceType]
ctxt SDoc
sdoc

pprIfaceForAllCoPart :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
                     -> SDoc -> SDoc
pprIfaceForAllCoPart :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
-> SDoc -> SDoc
pprIfaceForAllCoPart [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs SDoc
sdoc
  = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCo [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs, SDoc
sdoc ]

ppr_iface_forall_part :: ShowForAllFlag
                      -> [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
ppr_iface_forall_part :: ShowForAllFlag -> [IfaceForAllBndr] -> [IfaceType] -> SDoc -> SDoc
ppr_iface_forall_part ShowForAllFlag
show_forall [IfaceForAllBndr]
tvs [IfaceType]
ctxt SDoc
sdoc
  = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ case ShowForAllFlag
show_forall of
            ShowForAllFlag
ShowForAllMust -> [IfaceForAllBndr] -> SDoc
pprIfaceForAll [IfaceForAllBndr]
tvs
            ShowForAllFlag
ShowForAllWhen -> [IfaceForAllBndr] -> SDoc
pprUserIfaceForAll [IfaceForAllBndr]
tvs
        , [IfaceType] -> SDoc
pprIfaceContextArr [IfaceType]
ctxt
        , SDoc
sdoc]

-- | Render the "forall ... ." or "forall ... ->" bit of a type.
pprIfaceForAll :: [IfaceForAllBndr] -> SDoc
pprIfaceForAll :: [IfaceForAllBndr] -> SDoc
pprIfaceForAll [] = SDoc
forall doc. IsOutput doc => doc
empty
pprIfaceForAll bndrs :: [IfaceForAllBndr]
bndrs@(Bndr IfaceBndr
_ ForAllTyFlag
vis : [IfaceForAllBndr]
_)
  = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ SDoc -> SDoc
add_separator (SDoc
forAllLit SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
fsep [SDoc]
docs)
        , [IfaceForAllBndr] -> SDoc
pprIfaceForAll [IfaceForAllBndr]
bndrs' ]
  where
    ([IfaceForAllBndr]
bndrs', [SDoc]
docs) = [IfaceForAllBndr] -> ForAllTyFlag -> ([IfaceForAllBndr], [SDoc])
ppr_itv_bndrs [IfaceForAllBndr]
bndrs ForAllTyFlag
vis

    add_separator :: SDoc -> SDoc
add_separator SDoc
stuff = case ForAllTyFlag
vis of
                            ForAllTyFlag
Required -> SDoc
stuff SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
arrow
                            ForAllTyFlag
_inv     -> SDoc
stuff SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<>  SDoc
forall doc. IsLine doc => doc
dot


-- | Render the ... in @(forall ... .)@ or @(forall ... ->)@.
-- Returns both the list of not-yet-rendered binders and the doc.
-- No anonymous binders here!
ppr_itv_bndrs :: [IfaceForAllBndr]
             -> ForAllTyFlag  -- ^ visibility of the first binder in the list
             -> ([IfaceForAllBndr], [SDoc])
ppr_itv_bndrs :: [IfaceForAllBndr] -> ForAllTyFlag -> ([IfaceForAllBndr], [SDoc])
ppr_itv_bndrs all_bndrs :: [IfaceForAllBndr]
all_bndrs@(bndr :: IfaceForAllBndr
bndr@(Bndr IfaceBndr
_ ForAllTyFlag
vis) : [IfaceForAllBndr]
bndrs) ForAllTyFlag
vis1
  | ForAllTyFlag
vis ForAllTyFlag -> ForAllTyFlag -> Bool
`eqForAllVis` ForAllTyFlag
vis1 = let ([IfaceForAllBndr]
bndrs', [SDoc]
doc) = [IfaceForAllBndr] -> ForAllTyFlag -> ([IfaceForAllBndr], [SDoc])
ppr_itv_bndrs [IfaceForAllBndr]
bndrs ForAllTyFlag
vis1 in
                             ([IfaceForAllBndr]
bndrs', IfaceForAllBndr -> SDoc
pprIfaceForAllBndr IfaceForAllBndr
bndr SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: [SDoc]
doc)
  | Bool
otherwise              = ([IfaceForAllBndr]
all_bndrs, [])
ppr_itv_bndrs [] ForAllTyFlag
_ = ([], [])

pprIfaceForAllCo :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCo :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCo []  = SDoc
forall doc. IsOutput doc => doc
empty
pprIfaceForAllCo [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"forall" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCoBndrs [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
dot

pprIfaceForAllCoBndrs :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCoBndrs :: [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)] -> SDoc
pprIfaceForAllCoBndrs [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
bndrs = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ ((IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag) -> SDoc)
-> [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
-> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag) -> SDoc
pprIfaceForAllCoBndr [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
bndrs

pprIfaceForAllBndr :: IfaceForAllBndr -> SDoc
pprIfaceForAllBndr :: IfaceForAllBndr -> SDoc
pprIfaceForAllBndr IfaceForAllBndr
bndr =
  case IfaceForAllBndr
bndr of
    Bndr (IfaceTvBndr IfaceTvBndr
tv) ForAllTyFlag
Inferred ->
      SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
pprIfaceTvBndr IfaceTvBndr
tv SuppressBndrSig
suppress_sig (Bool -> UseBndrParens
UseBndrParens Bool
False)
    Bndr (IfaceTvBndr IfaceTvBndr
tv) ForAllTyFlag
_ ->
      IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
pprIfaceTvBndr IfaceTvBndr
tv SuppressBndrSig
suppress_sig (Bool -> UseBndrParens
UseBndrParens Bool
True)
    Bndr (IfaceIdBndr IfaceIdBndr
idv) ForAllTyFlag
_ -> IfaceIdBndr -> SDoc
pprIfaceIdBndr IfaceIdBndr
idv
  where
    -- See Note [Suppressing binder signatures]
    suppress_sig :: SuppressBndrSig
suppress_sig = Bool -> SuppressBndrSig
SuppressBndrSig Bool
False

pprIfaceForAllCoBndr :: (IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag) -> SDoc
pprIfaceForAllCoBndr :: (IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag) -> SDoc
pprIfaceForAllCoBndr (IfLclName
tv, IfaceCoercion
kind_co, ForAllTyFlag
visL, ForAllTyFlag
visR)
  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
pp_vis SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceCoercion -> SDoc
pprIfaceCoercion IfaceCoercion
kind_co)
  where
    pp_vis :: SDoc
pp_vis | ForAllTyFlag
visL ForAllTyFlag -> ForAllTyFlag -> Bool
forall a. Eq a => a -> a -> Bool
== ForAllTyFlag
coreTyLamForAllTyFlag
           , ForAllTyFlag
visR ForAllTyFlag -> ForAllTyFlag -> Bool
forall a. Eq a => a -> a -> Bool
== ForAllTyFlag
coreTyLamForAllTyFlag
           = SDoc
forall doc. IsOutput doc => doc
empty
           | Bool
otherwise
           = ForAllTyFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr ForAllTyFlag
visL SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'~' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> ForAllTyFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr ForAllTyFlag
visR    -- "[spec]~[reqd]"

-- | Show forall flag
--
-- Unconditionally show the forall quantifier with ('ShowForAllMust')
-- or when ('ShowForAllWhen') the names used are free in the binder
-- or when compiling with -fprint-explicit-foralls.
data ShowForAllFlag = ShowForAllMust | ShowForAllWhen

data ShowSub
  = ShowSub
      { ShowSub -> ShowHowMuch
ss_how_much :: ShowHowMuch
      , ShowSub -> ShowForAllFlag
ss_forall :: ShowForAllFlag }

-- See Note [Printing IfaceDecl binders]
-- The alternative pretty printer referred to in the note.
newtype AltPpr = AltPpr (Maybe (OccName -> SDoc))

data ShowHowMuch
  = ShowHeader AltPpr -- ^ Header information only, not rhs
  | ShowSome (Maybe (OccName -> Bool)) AltPpr
  -- ^ Show the declaration and its RHS. The @Maybe@ predicate
  -- allows filtering of the sub-components which should be printing;
  -- any sub-components filtered out will be elided with @...@.
  | ShowIface
  -- ^ Everything including GHC-internal information (used in --show-iface)

instance Outputable ShowHowMuch where
  ppr :: ShowHowMuch -> SDoc
ppr (ShowHeader AltPpr
_) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"ShowHeader"
  ppr ShowHowMuch
ShowIface      = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"ShowIface"
  ppr (ShowSome Maybe (OccName -> Bool)
_ AltPpr
_) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"ShowSome"

pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc
pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc
pprIfaceSigmaType ShowForAllFlag
show_forall IfaceType
ty
  = (IfaceType -> SDoc) -> IfaceType -> SDoc
hideNonStandardTypes (ShowForAllFlag -> PprPrec -> IfaceType -> SDoc
ppr_sigma ShowForAllFlag
show_forall PprPrec
topPrec) IfaceType
ty

ppr_sigma :: ShowForAllFlag -> PprPrec -> IfaceType -> SDoc
ppr_sigma :: ShowForAllFlag -> PprPrec -> IfaceType -> SDoc
ppr_sigma ShowForAllFlag
show_forall PprPrec
ctxt_prec IfaceType
iface_ty
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    let ([IfaceForAllBndr]
invis_tvs, [IfaceType]
theta, IfaceType
tau) = IfaceType -> ([IfaceForAllBndr], [IfaceType], IfaceType)
splitIfaceSigmaTy IfaceType
iface_ty
        ([IfaceForAllBndr]
req_tvs, IfaceType
tau') = IfaceType -> ([IfaceForAllBndr], IfaceType)
splitIfaceReqForallTy IfaceType
tau
          -- splitIfaceSigmaTy is recursive, so it will gather the binders after
          -- the theta, i.e.  forall a. theta => forall b. tau
          -- will give you    ([a,b], theta, tau).
          --
          -- This isn't right when it comes to visible forall (see
          --  testsuite/tests/polykinds/T18522-ppr),
          -- so we split off required binders separately,
          -- using splitIfaceReqForallTy.
          --
          -- An alternative solution would be to make splitIfaceSigmaTy
          -- non-recursive (see #18458).
          -- Then it could handle both invisible and required binders, and
          -- splitIfaceReqForallTy wouldn't be necessary here.
    in ShowForAllFlag -> [IfaceForAllBndr] -> [IfaceType] -> SDoc -> SDoc
ppr_iface_forall_part ShowForAllFlag
show_forall [IfaceForAllBndr]
invis_tvs [IfaceType]
theta (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
       [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [[IfaceForAllBndr] -> SDoc
pprIfaceForAll [IfaceForAllBndr]
req_tvs, IfaceType -> SDoc
ppr_ty_nested IfaceType
tau']

pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc
pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc
pprUserIfaceForAll [IfaceForAllBndr]
tvs
   = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitForalls ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_foralls ->
     -- See Note [When to print foralls] in this module.
     Bool -> SDoc -> SDoc
forall doc. IsOutput doc => Bool -> doc -> doc
ppWhen ((IfaceForAllBndr -> Bool) -> [IfaceForAllBndr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any IfaceForAllBndr -> Bool
forall {argf}. VarBndr IfaceBndr argf -> Bool
tv_has_kind_var [IfaceForAllBndr]
tvs
             Bool -> Bool -> Bool
|| (IfaceForAllBndr -> Bool) -> [IfaceForAllBndr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any IfaceForAllBndr -> Bool
forall {tv}. VarBndr tv ForAllTyFlag -> Bool
tv_is_required [IfaceForAllBndr]
tvs
             Bool -> Bool -> Bool
|| Bool
print_foralls) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
     [IfaceForAllBndr] -> SDoc
pprIfaceForAll [IfaceForAllBndr]
tvs
   where
     tv_has_kind_var :: VarBndr IfaceBndr argf -> Bool
tv_has_kind_var (Bndr (IfaceTvBndr (IfLclName
_,IfaceType
kind)) argf
_)
       = Bool -> Bool
not (IfaceType -> Bool
ifTypeIsVarFree IfaceType
kind)
     tv_has_kind_var VarBndr IfaceBndr argf
_ = Bool
False

     tv_is_required :: VarBndr tv ForAllTyFlag -> Bool
tv_is_required = ForAllTyFlag -> Bool
isVisibleForAllTyFlag (ForAllTyFlag -> Bool)
-> (VarBndr tv ForAllTyFlag -> ForAllTyFlag)
-> VarBndr tv ForAllTyFlag
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VarBndr tv ForAllTyFlag -> ForAllTyFlag
forall tv argf. VarBndr tv argf -> argf
binderFlag

{-
Note [When to print foralls]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We opt to explicitly pretty-print `forall`s if any of the following
criteria are met:

1. -fprint-explicit-foralls is on.

2. A bound type variable has a polymorphic kind. E.g.,

     forall k (a::k). Proxy a -> Proxy a

   Since a's kind mentions a variable k, we print the foralls.

3. A bound type variable is a visible argument (#14238).
   Suppose we are printing the kind of:

     T :: forall k -> k -> Type

   The "forall k ->" notation means that this kind argument is required.
   That is, it must be supplied at uses of T. E.g.,

     f :: T (Type->Type)  Monad -> Int

   So we print an explicit "T :: forall k -> k -> Type",
   because omitting it and printing "T :: k -> Type" would be
   utterly misleading.

   See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility]
   in GHC.Core.TyCo.Rep.

N.B. Until now (Aug 2018) we didn't check anything for coercion variables.

Note [Printing foralls in type family instances]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We use the same criteria as in Note [When to print foralls] to determine
whether a type family instance should be pretty-printed with an explicit
`forall`. Example:

  type family Foo (a :: k) :: k where
    Foo Maybe       = []
    Foo (a :: Type) = Int
    Foo a           = a

Without -fprint-explicit-foralls enabled, this will be pretty-printed as:

type family Foo (a :: k) :: k where
  Foo Maybe = []
  Foo a = Int
  forall k (a :: k). Foo a = a

Note that only the third equation has an explicit forall, since it has a type
variable with a non-Type kind. (If -fprint-explicit-foralls were enabled, then
the second equation would be preceded with `forall a.`.)

There is one tricky point in the implementation: what visibility
do we give the type variables in a type family instance? Type family instances
only store type *variables*, not type variable *binders*, and only the latter
has visibility information. We opt to default the visibility of each of these
type variables to Specified because users can't ever instantiate these
variables manually, so the choice of visibility is only relevant to
pretty-printing. (This is why the `k` in `forall k (a :: k). ...` above is
printed the way it is, even though it wasn't written explicitly in the
original source code.)

We adopt the same strategy for data family instances. Example:

  data family DF (a :: k)
  data instance DF '[a, b] = DFList

That data family instance is pretty-printed as:

  data instance forall j (a :: j) (b :: j). DF '[a, b] = DFList

This is despite that the representation tycon for this data instance (call it
$DF:List) actually has different visibilities for its binders.
However, the visibilities of these binders are utterly irrelevant to the
programmer, who cares only about the specificity of variables in `DF`'s type,
not $DF:List's type. Therefore, we opt to pretty-print all variables in data
family instances as Specified.

Note [Printing promoted type constructors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this GHCi session (#14343)
    > _ :: Proxy '[ 'True ]
    error:
      Found hole: _ :: Proxy '['True]

This would be bad, because the '[' looks like a character literal.

A similar issue arises if the element is a character literal (#22488)
    ghci> type T = '[ 'x' ]
    ghci> :kind! T
    T :: [Char]
    = '['x']

Solution: in type-level lists and tuples, add a leading space
if the first element is printed with a single quote.
-}


-------------------

-- See equivalent function in "GHC.Core.TyCo.Rep"
pprIfaceTyList :: PprPrec -> IfaceType -> IfaceType -> SDoc
-- Given a type-level list (t1 ': t2), see if we can print
-- it in list notation [t1, ...].
-- Precondition: Opt_PrintExplicitKinds is off
pprIfaceTyList :: PprPrec -> IfaceType -> IfaceType -> SDoc
pprIfaceTyList PprPrec
ctxt_prec IfaceType
ty1 IfaceType
ty2
  = case IfaceType -> ([IfaceType], Maybe IfaceType)
gather IfaceType
ty2 of
      ([IfaceType]
arg_tys, Maybe IfaceType
Nothing)
        ->
        (SDocContext -> SDoc) -> SDoc
sdocWithContext ((SDocContext -> SDoc) -> SDoc) -> (SDocContext -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \SDocContext
ctx ->
          let
            items :: [IfaceType]
items  = IfaceType
ty1IfaceType -> [IfaceType] -> [IfaceType]
forall a. a -> [a] -> [a]
:[IfaceType]
arg_tys
            eos :: IsEmptyOrSingleton
eos    = [IfaceType] -> IsEmptyOrSingleton
forall a. [a] -> IsEmptyOrSingleton
isListEmptyOrSingleton [IfaceType]
items
            ticked :: Bool
ticked = PprStyle -> QueryPromotionTick
promTick (SDocContext -> PprStyle
sdocStyle SDocContext
ctx) (IsEmptyOrSingleton -> PromotedItem
PromotedItemListSyntax IsEmptyOrSingleton
eos)
            (SDoc
preBracket, SDoc -> SDoc
postBracket) =
              if Bool
ticked
              then (Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'\'', SDoc -> SDoc
spaceIfSingleQuote)
              else (SDoc
forall doc. IsOutput doc => doc
empty, SDoc -> SDoc
forall a. a -> a
id)
          in
            SDoc
preBracket SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
brackets (SDoc -> SDoc
postBracket ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
fsep
                          (SDoc -> [SDoc] -> [SDoc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate SDoc
forall doc. IsLine doc => doc
comma ((IfaceType -> SDoc) -> [IfaceType] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
topPrec) [IfaceType]
items))))
      ([IfaceType]
arg_tys, Just IfaceType
tl)
        -> PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> Int -> SDoc -> SDoc
hang (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
funPrec IfaceType
ty1)
           Int
2 ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
fsep [ SDoc
forall doc. IsLine doc => doc
colon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
funPrec IfaceType
ty | IfaceType
ty <- [IfaceType]
arg_tys [IfaceType] -> [IfaceType] -> [IfaceType]
forall a. [a] -> [a] -> [a]
++ [IfaceType
tl]])
  where
    gather :: IfaceType -> ([IfaceType], Maybe IfaceType)
     -- (gather ty) = (tys, Nothing) means ty is a list [t1, .., tn]
     --             = (tys, Just tl) means ty is of form t1:t2:...tn:tl
    gather :: IfaceType -> ([IfaceType], Maybe IfaceType)
gather (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys)
      | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
consDataConKey
      , IA_Arg IfaceType
_ ForAllTyFlag
argf (IA_Arg IfaceType
ty1 ForAllTyFlag
Required (IA_Arg IfaceType
ty2 ForAllTyFlag
Required IfaceAppArgs
IA_Nil)) <- IfaceAppArgs
tys
      , ForAllTyFlag -> Bool
isInvisibleForAllTyFlag ForAllTyFlag
argf
      , ([IfaceType]
args, Maybe IfaceType
tl) <- IfaceType -> ([IfaceType], Maybe IfaceType)
gather IfaceType
ty2
      = (IfaceType
ty1IfaceType -> [IfaceType] -> [IfaceType]
forall a. a -> [a] -> [a]
:[IfaceType]
args, Maybe IfaceType
tl)
      | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
nilDataConKey
      = ([], Maybe IfaceType
forall a. Maybe a
Nothing)
    gather IfaceType
ty = ([], IfaceType -> Maybe IfaceType
forall a. a -> Maybe a
Just IfaceType
ty)

pprIfaceTypeApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprIfaceTypeApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprIfaceTypeApp PprPrec
prec IfaceTyCon
tc IfaceAppArgs
args = PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprTyTcApp PprPrec
prec IfaceTyCon
tc IfaceAppArgs
args

pprTyTcApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprTyTcApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprTyTcApp PprPrec
ctxt_prec IfaceTyCon
tc IfaceAppArgs
tys =
    (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitKinds ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_kinds ->
    (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintTypeAbbreviations ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_type_abbreviations ->
    (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 | IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
ipClassKey
       , IA_Arg (IfaceLitTy (IfaceStrTyLit LexicalFastString
n))
                ForAllTyFlag
Required (IA_Arg IfaceType
ty ForAllTyFlag
Required IfaceAppArgs
IA_Nil) <- IfaceAppArgs
tys
       -> PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
funPrec
         (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'?' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext (LexicalFastString -> FastString
getLexicalFastString LexicalFastString
n) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"::" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
topPrec IfaceType
ty

       | IfaceTupleTyCon Int
arity TupleSort
sort <- IfaceTyConInfo -> IfaceTyConSort
ifaceTyConSort IfaceTyConInfo
info
       , Bool -> Bool
not Bool
debug
       , Int
arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== IfaceAppArgs -> Int
ifaceVisAppArgsLength IfaceAppArgs
tys
       -> PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple PprPrec
ctxt_prec TupleSort
sort (IfaceTyConInfo -> PromotionFlag
ifaceTyConIsPromoted IfaceTyConInfo
info) IfaceAppArgs
tys
           -- NB: ppr_tuple requires a saturated tuple.

       | IfaceSumTyCon Int
arity <- IfaceTyConInfo -> IfaceTyConSort
ifaceTyConSort IfaceTyConInfo
info
       , Bool -> Bool
not Bool
debug
       , Int
arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== IfaceAppArgs -> Int
ifaceVisAppArgsLength IfaceAppArgs
tys
       -> PprPrec -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_sum PprPrec
ctxt_prec (IfaceTyConInfo -> PromotionFlag
ifaceTyConIsPromoted IfaceTyConInfo
info) IfaceAppArgs
tys
           -- NB: ppr_sum requires a saturated unboxed sum.

       | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
consDataConKey
       , Bool
False <- Bool
print_kinds
       , IA_Arg IfaceType
_ ForAllTyFlag
argf (IA_Arg IfaceType
ty1 ForAllTyFlag
Required (IA_Arg IfaceType
ty2 ForAllTyFlag
Required IfaceAppArgs
IA_Nil)) <- IfaceAppArgs
tys
       , ForAllTyFlag -> Bool
isInvisibleForAllTyFlag ForAllTyFlag
argf
       -> PprPrec -> IfaceType -> IfaceType -> SDoc
pprIfaceTyList PprPrec
ctxt_prec IfaceType
ty1 IfaceType
ty2

       | IfaceType -> Bool
isIfaceLiftedTypeKind (IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys)
       , Bool
print_type_abbreviations  -- See Note [Printing type abbreviations]
       -> PprPrec -> SDoc
ppr_kind_type PprPrec
ctxt_prec

       | IfaceType -> Bool
isIfaceConstraintKind (IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys)
       , Bool
print_type_abbreviations  -- See Note [Printing type abbreviations]
       -> IfExtName -> SDoc
forall a. OutputableBndr a => a -> SDoc
pprPrefixOcc IfExtName
constraintKindTyConName

       | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
fUNTyConKey
       , IA_Arg (IfaceTyConApp IfaceTyCon
rep IfaceAppArgs
IA_Nil) ForAllTyFlag
Required IfaceAppArgs
args <- IfaceAppArgs
tys
       , IfaceTyCon
rep IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
manyDataConKey
       , Bool
print_type_abbreviations  -- See Note [Printing type abbreviations]
       -> PprPrec -> SDoc -> [SDoc] -> SDoc
pprIfacePrefixApp PprPrec
ctxt_prec (SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens SDoc
arrow) (((IfaceType, ForAllTyFlag) -> SDoc)
-> [(IfaceType, ForAllTyFlag)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc
ppr_app_arg PprPrec
appPrec) ([(IfaceType, ForAllTyFlag)] -> [SDoc])
-> [(IfaceType, ForAllTyFlag)] -> [SDoc]
forall a b. (a -> b) -> a -> b
$
          IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
appArgsIfaceTypesForAllTyFlags (IfaceAppArgs -> [(IfaceType, ForAllTyFlag)])
-> IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
forall a b. (a -> b) -> a -> b
$
          PrintExplicitKinds -> IfaceAppArgs -> IfaceAppArgs
stripInvisArgs (Bool -> PrintExplicitKinds
PrintExplicitKinds Bool
print_kinds) IfaceAppArgs
args)
          -- Use appArgsIfaceTypesForAllTyFlags to print invisible arguments
          -- correctly (#19310)

       | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
errorMessageTypeErrorFamKey
       , Bool -> Bool
not Bool
debug
         -- Suppress detail unless you _really_ want to see
       -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"(TypeError ...)"

       | Just SDoc
doc <- PprPrec -> IfaceTyCon -> [IfaceType] -> Maybe SDoc
ppr_equality PprPrec
ctxt_prec IfaceTyCon
tc (IfaceAppArgs -> [IfaceType]
appArgsIfaceTypes IfaceAppArgs
tys)
       -> SDoc
doc

       | Bool
otherwise
       -> (PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc)
-> PprPrec -> IfaceTyCon -> [(IfaceType, ForAllTyFlag)] -> SDoc
forall a.
(PprPrec -> (a, ForAllTyFlag) -> SDoc)
-> PprPrec -> IfaceTyCon -> [(a, ForAllTyFlag)] -> SDoc
ppr_iface_tc_app PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc
ppr_app_arg PprPrec
ctxt_prec IfaceTyCon
tc ([(IfaceType, ForAllTyFlag)] -> SDoc)
-> [(IfaceType, ForAllTyFlag)] -> SDoc
forall a b. (a -> b) -> a -> b
$
          IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
appArgsIfaceTypesForAllTyFlags (IfaceAppArgs -> [(IfaceType, ForAllTyFlag)])
-> IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
forall a b. (a -> b) -> a -> b
$ PrintExplicitKinds -> IfaceAppArgs -> IfaceAppArgs
stripInvisArgs (Bool -> PrintExplicitKinds
PrintExplicitKinds Bool
print_kinds) IfaceAppArgs
tys
  where
    info :: IfaceTyConInfo
info = IfaceTyCon -> IfaceTyConInfo
ifaceTyConInfo IfaceTyCon
tc

ppr_kind_type :: PprPrec -> SDoc
ppr_kind_type :: PprPrec -> SDoc
ppr_kind_type PprPrec
ctxt_prec = (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocStarIsType ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \case
   Bool
False -> IfExtName -> SDoc
forall a. OutputableBndr a => a -> SDoc
pprPrefixOcc IfExtName
liftedTypeKindTyConName
   Bool
True  -> PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
starPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
              SDoc -> SDoc -> SDoc
unicodeSyntax (Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'★') (Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'*')

-- | Pretty-print a type-level equality.
-- Returns (Just doc) if the argument is a /saturated/ application
-- of   eqTyCon          (~)
--      eqPrimTyCon      (~#)
--      eqReprPrimTyCon  (~R#)
--      heqTyCon         (~~)
--
-- See Note [Equality predicates in IfaceType]
-- and Note [The equality types story] in GHC.Builtin.Types.Prim
ppr_equality :: PprPrec -> IfaceTyCon -> [IfaceType] -> Maybe SDoc
ppr_equality :: PprPrec -> IfaceTyCon -> [IfaceType] -> Maybe SDoc
ppr_equality PprPrec
ctxt_prec IfaceTyCon
tc [IfaceType]
args
  | Bool
hetero_eq_tc
  , [IfaceType
k1, IfaceType
k2, IfaceType
t1, IfaceType
t2] <- [IfaceType]
args
  = SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just (SDoc -> Maybe SDoc) -> SDoc -> Maybe SDoc
forall a b. (a -> b) -> a -> b
$ (IfaceType, IfaceType, IfaceType, IfaceType) -> SDoc
print_equality (IfaceType
k1, IfaceType
k2, IfaceType
t1, IfaceType
t2)

  | Bool
hom_eq_tc
  , [IfaceType
k, IfaceType
t1, IfaceType
t2] <- [IfaceType]
args
  = SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just (SDoc -> Maybe SDoc) -> SDoc -> Maybe SDoc
forall a b. (a -> b) -> a -> b
$ (IfaceType, IfaceType, IfaceType, IfaceType) -> SDoc
print_equality (IfaceType
k, IfaceType
k, IfaceType
t1, IfaceType
t2)

  | Bool
otherwise
  = Maybe SDoc
forall a. Maybe a
Nothing
  where
    homogeneous :: Bool
homogeneous = IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqTyConKey -- (~)
               Bool -> Bool -> Bool
|| Bool
hetero_tc_used_homogeneously
      where
        hetero_tc_used_homogeneously :: Bool
hetero_tc_used_homogeneously
          = case IfaceTyConInfo -> IfaceTyConSort
ifaceTyConSort (IfaceTyConInfo -> IfaceTyConSort)
-> IfaceTyConInfo -> IfaceTyConSort
forall a b. (a -> b) -> a -> b
$ IfaceTyCon -> IfaceTyConInfo
ifaceTyConInfo IfaceTyCon
tc of
                          IfaceTyConSort
IfaceEqualityTyCon -> Bool
True
                          IfaceTyConSort
_other             -> Bool
False
             -- True <=> a heterogeneous equality whose arguments
             --          are (in this case) of the same kind

    tc_name :: IfExtName
tc_name = IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc
    pp :: PprPrec -> IfaceType -> SDoc
pp = PprPrec -> IfaceType -> SDoc
ppr_ty
    hom_eq_tc :: Bool
hom_eq_tc = IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqTyConKey            -- (~)
    hetero_eq_tc :: Bool
hetero_eq_tc = IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqPrimTyConKey     -- (~#)
                Bool -> Bool -> Bool
|| IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqReprPrimTyConKey -- (~R#)
                Bool -> Bool -> Bool
|| IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
heqTyConKey        -- (~~)
    nominal_eq_tc :: Bool
nominal_eq_tc = IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
heqTyConKey       -- (~~)
                 Bool -> Bool -> Bool
|| IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqPrimTyConKey    -- (~#)
    print_equality :: (IfaceType, IfaceType, IfaceType, IfaceType) -> SDoc
print_equality (IfaceType, IfaceType, IfaceType, IfaceType)
args =
        (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintExplicitKinds ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_kinds ->
        (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocPrintEqualityRelations ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
print_eqs ->
        (PprStyle -> SDoc) -> SDoc
getPprStyle      ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
style  ->
        (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  ->
        (IfaceType, IfaceType, IfaceType, IfaceType)
-> Bool -> Bool -> SDoc
print_equality' (IfaceType, IfaceType, IfaceType, IfaceType)
args Bool
print_kinds
          (Bool
print_eqs Bool -> Bool -> Bool
|| PprStyle -> Bool
dumpStyle PprStyle
style Bool -> Bool -> Bool
|| Bool
debug)

    print_equality' :: (IfaceType, IfaceType, IfaceType, IfaceType)
-> Bool -> Bool -> SDoc
print_equality' (IfaceType
ki1, IfaceType
ki2, IfaceType
ty1, IfaceType
ty2) Bool
print_kinds Bool
print_eqs
      | -- If -fprint-equality-relations is on, just print the original TyCon
        Bool
print_eqs
      = SDoc -> SDoc
ppr_infix_eq (IfaceTyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceTyCon
tc)

      | -- Homogeneous use of heterogeneous equality (ty1 ~~ ty2)
        --                 or unlifted equality      (ty1 ~# ty2)
        Bool
nominal_eq_tc, Bool
homogeneous
      = SDoc -> SDoc
ppr_infix_eq (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"~")

      | -- Heterogeneous use of unlifted equality (ty1 ~# ty2)
        Bool -> Bool
not Bool
homogeneous
      = SDoc -> SDoc
ppr_infix_eq (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
heqTyCon)

      | -- Homogeneous use of representational unlifted equality (ty1 ~R# ty2)
        IfExtName
tc_name IfExtName -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqReprPrimTyConKey, Bool
homogeneous
      = let ki :: [SDoc]
ki | Bool
print_kinds = [PprPrec -> IfaceType -> SDoc
pp PprPrec
appPrec IfaceType
ki1]
               | Bool
otherwise   = []
        in PprPrec -> SDoc -> [SDoc] -> SDoc
pprIfacePrefixApp PprPrec
ctxt_prec (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
coercibleTyCon)
                            ([SDoc]
ki [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++ [PprPrec -> IfaceType -> SDoc
pp PprPrec
appPrec IfaceType
ty1, PprPrec -> IfaceType -> SDoc
pp PprPrec
appPrec IfaceType
ty2])

        -- The other cases work as you'd expect
      | Bool
otherwise
      = SDoc -> SDoc
ppr_infix_eq (IfaceTyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceTyCon
tc)
      where
        ppr_infix_eq :: SDoc -> SDoc
        ppr_infix_eq :: SDoc -> SDoc
ppr_infix_eq SDoc
eq_op = PprPrec -> SDoc -> SDoc -> SDoc -> SDoc
pprIfaceInfixApp PprPrec
ctxt_prec SDoc
eq_op
                               (IfaceType -> IfaceType -> SDoc
pp_ty_ki IfaceType
ty1 IfaceType
ki1) (IfaceType -> IfaceType -> SDoc
pp_ty_ki IfaceType
ty2 IfaceType
ki2)
          where
            pp_ty_ki :: IfaceType -> IfaceType -> SDoc
pp_ty_ki IfaceType
ty IfaceType
ki
              | Bool
print_kinds
              = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (PprPrec -> IfaceType -> SDoc
pp PprPrec
topPrec IfaceType
ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceType -> SDoc
pp PprPrec
opPrec IfaceType
ki)
              | Bool
otherwise
              = PprPrec -> IfaceType -> SDoc
pp PprPrec
opPrec IfaceType
ty


pprIfaceCoTcApp :: PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc
pprIfaceCoTcApp :: PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc
pprIfaceCoTcApp PprPrec
ctxt_prec IfaceTyCon
tc [IfaceCoercion]
tys =
  (PprPrec -> (IfaceCoercion, ForAllTyFlag) -> SDoc)
-> PprPrec -> IfaceTyCon -> [(IfaceCoercion, ForAllTyFlag)] -> SDoc
forall a.
(PprPrec -> (a, ForAllTyFlag) -> SDoc)
-> PprPrec -> IfaceTyCon -> [(a, ForAllTyFlag)] -> SDoc
ppr_iface_tc_app (\PprPrec
prec (IfaceCoercion
co, ForAllTyFlag
_) -> PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
prec IfaceCoercion
co) PprPrec
ctxt_prec IfaceTyCon
tc
    ((IfaceCoercion -> (IfaceCoercion, ForAllTyFlag))
-> [IfaceCoercion] -> [(IfaceCoercion, ForAllTyFlag)]
forall a b. (a -> b) -> [a] -> [b]
map (, ForAllTyFlag
Required) [IfaceCoercion]
tys)
    -- We are trying to re-use ppr_iface_tc_app here, which requires its
    -- arguments to be accompanied by visibilities. But visibility is
    -- irrelevant when printing coercions, so just default everything to
    -- Required.

-- | Pretty-prints an application of a type constructor to some arguments
-- (whose visibilities are known). This is polymorphic (over @a@) since we use
-- this function to pretty-print two different things:
--
-- 1. Types (from `pprTyTcApp'`)
--
-- 2. Coercions (from 'pprIfaceCoTcApp')
ppr_iface_tc_app :: (PprPrec -> (a, ForAllTyFlag) -> SDoc)
                 -> PprPrec -> IfaceTyCon -> [(a, ForAllTyFlag)] -> SDoc

ppr_iface_tc_app :: forall a.
(PprPrec -> (a, ForAllTyFlag) -> SDoc)
-> PprPrec -> IfaceTyCon -> [(a, ForAllTyFlag)] -> SDoc
ppr_iface_tc_app PprPrec -> (a, ForAllTyFlag) -> SDoc
pp PprPrec
ctxt_prec IfaceTyCon
tc [(a, ForAllTyFlag)]
tys =
  (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocListTuplePuns ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Bool
listTuplePuns ->
  if | Bool
listTuplePuns, IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
listTyConKey, [(a, ForAllTyFlag)
ty] <- [(a, ForAllTyFlag)]
tys
     -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
brackets (PprPrec -> (a, ForAllTyFlag) -> SDoc
pp PprPrec
topPrec (a, ForAllTyFlag)
ty)

     | IfaceTyCon
tc IfaceTyCon -> Unique -> Bool
`ifaceTyConHasKey` Unique
liftedTypeKindTyConKey
     -> PprPrec -> SDoc
ppr_kind_type PprPrec
ctxt_prec

     | OccName -> Bool
isSymOcc (IfExtName -> OccName
nameOccName (IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc))

     , [ ty1 :: (a, ForAllTyFlag)
ty1@(a
_, ForAllTyFlag
Required), ty2 :: (a, ForAllTyFlag)
ty2@(a
_, ForAllTyFlag
Required) ] <- [(a, ForAllTyFlag)]
tys
         -- Infix, two visible arguments (we know nothing of precedence though).
         -- Don't apply this special case if one of the arguments is invisible,
         -- lest we print something like (@LiftedRep -> @LiftedRep) (#15941).
     -> PprPrec -> SDoc -> SDoc -> SDoc -> SDoc
pprIfaceInfixApp PprPrec
ctxt_prec (IfaceTyCon -> SDoc
pprIfaceTyCon IfaceTyCon
tc) (PprPrec -> (a, ForAllTyFlag) -> SDoc
pp PprPrec
opPrec (a, ForAllTyFlag)
ty1) (PprPrec -> (a, ForAllTyFlag) -> SDoc
pp PprPrec
opPrec (a, ForAllTyFlag)
ty2)

     | Bool
otherwise
     -> PprPrec -> SDoc -> [SDoc] -> SDoc
pprIfacePrefixApp PprPrec
ctxt_prec (IfaceTyCon -> SDoc
pprParendIfaceTyCon IfaceTyCon
tc) (((a, ForAllTyFlag) -> SDoc) -> [(a, ForAllTyFlag)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> (a, ForAllTyFlag) -> SDoc
pp PprPrec
appPrec) [(a, ForAllTyFlag)]
tys)

data TupleOrSum = IsSum | IsTuple TupleSort
  deriving (TupleOrSum -> TupleOrSum -> Bool
(TupleOrSum -> TupleOrSum -> Bool)
-> (TupleOrSum -> TupleOrSum -> Bool) -> Eq TupleOrSum
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TupleOrSum -> TupleOrSum -> Bool
== :: TupleOrSum -> TupleOrSum -> Bool
$c/= :: TupleOrSum -> TupleOrSum -> Bool
/= :: TupleOrSum -> TupleOrSum -> Bool
Eq)

-- | Pretty-print a boxed tuple datacon in regular tuple syntax.
-- Used when -XListTuplePuns is disabled.
ppr_tuple_no_pun :: PprPrec -> [IfaceType] -> SDoc
ppr_tuple_no_pun :: PprPrec -> [IfaceType] -> SDoc
ppr_tuple_no_pun PprPrec
ctxt_prec = \case
  [IfaceType
t] -> PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
appPrec (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"MkSolo" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
appPrec IfaceType
t)
  [IfaceType]
tys -> TupleSort -> SDoc -> SDoc
tupleParens TupleSort
BoxedTuple ((IfaceType -> SDoc) -> [IfaceType] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas IfaceType -> SDoc
pprIfaceType [IfaceType]
tys)

-- | Pretty-print an unboxed tuple or sum type in its parenthesized, punned, form.
-- Used when -XListTuplePuns is enabled.
--
-- The tycon should be saturated:
-- as many visible arguments as the arity of the sum or tuple.
--
-- NB: this always strips off the invisible 'RuntimeRep' arguments,
-- even with `-fprint-explicit-runtime-reps` and `-fprint-explicit-kinds`.
ppr_tuple_sum_pun :: PprPrec -> TupleOrSum -> PromotionFlag -> IfaceType -> Arity -> [IfaceType] -> SDoc
ppr_tuple_sum_pun :: PprPrec
-> TupleOrSum
-> PromotionFlag
-> IfaceType
-> Int
-> [IfaceType]
-> SDoc
ppr_tuple_sum_pun PprPrec
ctxt_prec TupleOrSum
sort PromotionFlag
promoted IfaceType
tc Int
arity [IfaceType]
tys
  | TupleOrSum
IsSum <- TupleOrSum
sort
  = SDoc -> SDoc
sumParens ((IfaceType -> SDoc) -> [IfaceType] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithBars (PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
topPrec) [IfaceType]
tys)

  |  IsTuple TupleSort
ConstraintTuple <- TupleOrSum
sort
  ,  PromotionFlag
NotPromoted <- PromotionFlag
promoted
  ,  Int
arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
sigPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"() :: Constraint"

  -- Special-case unary boxed tuples so that they are pretty-printed as
  -- `Solo x`, not `(x)`
  | IsTuple TupleSort
BoxedTuple <- TupleOrSum
sort
  , Int
arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
  = PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
ctxt_prec IfaceType
tc

  | IsTuple TupleSort
tupleSort <- TupleOrSum
sort
  = PromotionFlag -> SDoc
pprPromotionQuoteI PromotionFlag
promoted SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<>
    TupleSort -> SDoc -> SDoc
tupleParens TupleSort
tupleSort (SDoc -> SDoc
quote_space ((IfaceType -> SDoc) -> [IfaceType] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas IfaceType -> SDoc
pprIfaceType [IfaceType]
tys))
  where
    quote_space :: SDoc -> SDoc
quote_space = case PromotionFlag
promoted of
      PromotionFlag
IsPromoted -> SDoc -> SDoc
spaceIfSingleQuote
      PromotionFlag
NotPromoted -> SDoc -> SDoc
forall a. a -> a
id

-- | Pretty-print an unboxed tuple or sum type either in the punned or unpunned form,
-- depending on whether -XListTuplePuns is enabled.
ppr_tuple_sum :: PprPrec -> TupleOrSum -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple_sum :: PprPrec -> TupleOrSum -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple_sum PprPrec
ctxt_prec TupleOrSum
sort PromotionFlag
is_promoted IfaceAppArgs
args =
  (SDocContext -> Bool) -> (Bool -> SDoc) -> SDoc
forall a. (SDocContext -> a) -> (a -> SDoc) -> SDoc
sdocOption SDocContext -> Bool
sdocListTuplePuns ((Bool -> SDoc) -> SDoc) -> (Bool -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \case
    Bool
True -> PprPrec
-> TupleOrSum
-> PromotionFlag
-> IfaceType
-> Int
-> [IfaceType]
-> SDoc
ppr_tuple_sum_pun PprPrec
ctxt_prec TupleOrSum
sort PromotionFlag
is_promoted IfaceType
prefix_tc Int
arity [IfaceType]
non_rep_tys
    Bool
False
      | PromotionFlag
IsPromoted <- PromotionFlag
is_promoted
      , IsTuple TupleSort
BoxedTuple <- TupleOrSum
sort
      -> PprPrec -> [IfaceType] -> SDoc
ppr_tuple_no_pun PprPrec
ctxt_prec [IfaceType]
non_rep_tys
      | Bool
otherwise
      -> PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
ctxt_prec IfaceType
prefix_tc
  where
    -- This tycon is used to print in prefix notation for the punned Solo
    -- case and the unabbreviated case.
    prefix_tc :: IfaceType
prefix_tc = IfaceTyCon -> IfaceAppArgs -> IfaceType
IfaceTyConApp (IfExtName -> IfaceTyConInfo -> IfaceTyCon
IfaceTyCon (Int -> IfExtName
mk_name Int
arity) IfaceTyConInfo
info) IfaceAppArgs
args

    info :: IfaceTyConInfo
info = PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo PromotionFlag
NotPromoted IfaceTyConSort
IfaceNormalTyCon

    mk_name :: Int -> IfExtName
mk_name = case (TupleOrSum
sort, PromotionFlag
is_promoted) of
      (IsTuple TupleSort
BoxedTuple, PromotionFlag
IsPromoted) -> Boxity -> Int -> IfExtName
tupleDataConName Boxity
Boxed
      (IsTuple TupleSort
s, PromotionFlag
_) -> TupleSort -> Int -> IfExtName
tupleTyConName TupleSort
s
      (TupleOrSum
IsSum, PromotionFlag
_) -> TyCon -> IfExtName
tyConName (TyCon -> IfExtName) -> (Int -> TyCon) -> Int -> IfExtName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> TyCon
sumTyCon

    -- drop the RuntimeRep vars.
    -- See Note [Unboxed tuple RuntimeRep vars] in GHC.Core.TyCon
    non_rep_tys :: [IfaceType]
non_rep_tys = if Bool
strip_reps then Int -> [IfaceType] -> [IfaceType]
forall a. Int -> [a] -> [a]
drop Int
arity [IfaceType]
all_tys else [IfaceType]
all_tys

    arity :: Int
arity = if Bool
strip_reps then Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2 else Int
count

    count :: Int
count = [IfaceType] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [IfaceType]
all_tys

    all_tys :: [IfaceType]
all_tys = IfaceAppArgs -> [IfaceType]
appArgsIfaceTypes IfaceAppArgs
args

    strip_reps :: Bool
strip_reps = case PromotionFlag
is_promoted of
      PromotionFlag
IsPromoted -> Bool
True
      PromotionFlag
NotPromoted -> Bool
strip_reps_sort

    strip_reps_sort :: Bool
strip_reps_sort = case TupleOrSum
sort of
      IsTuple TupleSort
BoxedTuple -> Bool
False
      IsTuple TupleSort
UnboxedTuple -> Bool
True
      IsTuple TupleSort
ConstraintTuple -> Bool
False
      TupleOrSum
IsSum -> Bool
True

-- | Pretty-print an unboxed sum type.
-- The sum should be saturated: as many visible arguments as the arity of
-- the sum.
ppr_sum :: PprPrec -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_sum :: PprPrec -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_sum PprPrec
ctxt_prec = PprPrec -> TupleOrSum -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple_sum PprPrec
ctxt_prec TupleOrSum
IsSum

-- | Pretty-print a tuple type (boxed tuple, constraint tuple, unboxed tuple).
-- The tuple should be saturated: as many visible arguments as the arity of
-- the tuple.
ppr_tuple :: PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple :: PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple PprPrec
ctxt_prec TupleSort
sort = PprPrec -> TupleOrSum -> PromotionFlag -> IfaceAppArgs -> SDoc
ppr_tuple_sum PprPrec
ctxt_prec (TupleSort -> TupleOrSum
IsTuple TupleSort
sort)

pprIfaceTyLit :: IfaceTyLit -> SDoc
pprIfaceTyLit :: IfaceTyLit -> SDoc
pprIfaceTyLit (IfaceNumTyLit Integer
n) = Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
n
pprIfaceTyLit (IfaceStrTyLit LexicalFastString
n) = String -> SDoc
forall doc. IsLine doc => String -> doc
text (LexicalFastString -> String
forall a. Show a => a -> String
show LexicalFastString
n)
pprIfaceTyLit (IfaceCharTyLit Char
c) = String -> SDoc
forall doc. IsLine doc => String -> doc
text (Char -> String
forall a. Show a => a -> String
show Char
c)

pprIfaceCoercion, pprParendIfaceCoercion :: IfaceCoercion -> SDoc
pprIfaceCoercion :: IfaceCoercion -> SDoc
pprIfaceCoercion = PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
topPrec
pprParendIfaceCoercion :: IfaceCoercion -> SDoc
pprParendIfaceCoercion = PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
appPrec

ppr_co :: PprPrec -> IfaceCoercion -> SDoc
ppr_co :: PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
_         (IfaceReflCo IfaceType
ty) = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
angleBrackets (IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Role -> SDoc
ppr_role Role
Nominal
ppr_co PprPrec
_         (IfaceGReflCo Role
r IfaceType
ty IfaceMCoercion
IfaceMRefl)
  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
angleBrackets (IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Role -> SDoc
ppr_role Role
r
ppr_co PprPrec
ctxt_prec (IfaceGReflCo Role
r IfaceType
ty (IfaceMCo IfaceCoercion
co))
  = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec
    (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"GRefl" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr Role
r SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceType -> SDoc
pprParendIfaceType IfaceType
ty) [IfaceCoercion
co]

ppr_co PprPrec
ctxt_prec (IfaceFunCo Role
r IfaceCoercion
co_mult IfaceCoercion
co1 IfaceCoercion
co2)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep (PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
funPrec IfaceCoercion
co1 SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: IfaceCoercion -> IfaceCoercion -> [SDoc]
ppr_fun_tail IfaceCoercion
co_mult IfaceCoercion
co2)
  where
    ppr_fun_tail :: IfaceCoercion -> IfaceCoercion -> [SDoc]
ppr_fun_tail IfaceCoercion
co_mult1 (IfaceFunCo Role
r IfaceCoercion
co_mult2 IfaceCoercion
co1 IfaceCoercion
co2)
      = (IfaceCoercion -> SDoc
ppr_arrow IfaceCoercion
co_mult1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Role -> SDoc
ppr_role Role
r SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
funPrec IfaceCoercion
co1)
        SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: IfaceCoercion -> IfaceCoercion -> [SDoc]
ppr_fun_tail IfaceCoercion
co_mult2 IfaceCoercion
co2
    ppr_fun_tail IfaceCoercion
co_mult1 IfaceCoercion
other_co
      = [IfaceCoercion -> SDoc
ppr_arrow IfaceCoercion
co_mult1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Role -> SDoc
ppr_role Role
r SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceCoercion -> SDoc
pprIfaceCoercion IfaceCoercion
other_co]

    ppr_arrow :: IfaceCoercion -> SDoc
ppr_arrow = (IfaceCoercion -> Maybe IfaceTyCon,
 PprPrec -> IfaceCoercion -> SDoc)
-> FunTyFlag -> IfaceCoercion -> SDoc
forall a.
(a -> Maybe IfaceTyCon, PprPrec -> a -> SDoc)
-> FunTyFlag -> a -> SDoc
pprArrow (IfaceCoercion -> Maybe IfaceTyCon
mb_conc, PprPrec -> IfaceCoercion -> SDoc
ppr_co) FunTyFlag
visArgTypeLike
    mb_conc :: IfaceCoercion -> Maybe IfaceTyCon
mb_conc (IfaceTyConAppCo Role
_ IfaceTyCon
tc [IfaceCoercion]
_) = IfaceTyCon -> Maybe IfaceTyCon
forall a. a -> Maybe a
Just IfaceTyCon
tc
    mb_conc IfaceCoercion
_                        = Maybe IfaceTyCon
forall a. Maybe a
Nothing

ppr_co PprPrec
_         (IfaceTyConAppCo Role
r IfaceTyCon
tc [IfaceCoercion]
cos)
  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc
pprIfaceCoTcApp PprPrec
topPrec IfaceTyCon
tc [IfaceCoercion]
cos) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Role -> SDoc
ppr_role Role
r
ppr_co PprPrec
ctxt_prec (IfaceAppCo IfaceCoercion
co1 IfaceCoercion
co2)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
appPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
funPrec IfaceCoercion
co1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceCoercion -> SDoc
pprParendIfaceCoercion IfaceCoercion
co2
ppr_co PprPrec
ctxt_prec co :: IfaceCoercion
co@(IfaceForAllCo {})
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    -- FIXME: collect and pretty-print visibility info?
    [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
-> SDoc -> SDoc
pprIfaceForAllCoPart [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs (IfaceCoercion -> SDoc
pprIfaceCoercion IfaceCoercion
inner_co)
  where
    ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs, IfaceCoercion
inner_co) = IfaceCoercion
-> ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)],
    IfaceCoercion)
split_co IfaceCoercion
co

    split_co :: IfaceCoercion
-> ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)],
    IfaceCoercion)
split_co (IfaceForAllCo (IfaceTvBndr (IfLclName
name, IfaceType
_)) ForAllTyFlag
visL ForAllTyFlag
visR IfaceCoercion
kind_co IfaceCoercion
co')
      = let ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs, IfaceCoercion
co'') = IfaceCoercion
-> ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)],
    IfaceCoercion)
split_co IfaceCoercion
co' in ((IfLclName
name,IfaceCoercion
kind_co,ForAllTyFlag
visL,ForAllTyFlag
visR)(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)
-> [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
-> [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
forall a. a -> [a] -> [a]
:[(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs,IfaceCoercion
co'')
    split_co (IfaceForAllCo (IfaceIdBndr (IfaceType
_, IfLclName
name, IfaceType
_)) ForAllTyFlag
visL ForAllTyFlag
visR IfaceCoercion
kind_co IfaceCoercion
co')
      = let ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs, IfaceCoercion
co'') = IfaceCoercion
-> ([(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)],
    IfaceCoercion)
split_co IfaceCoercion
co' in ((IfLclName
name,IfaceCoercion
kind_co,ForAllTyFlag
visL,ForAllTyFlag
visR)(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)
-> [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
-> [(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
forall a. a -> [a] -> [a]
:[(IfLclName, IfaceCoercion, ForAllTyFlag, ForAllTyFlag)]
tvs,IfaceCoercion
co'')
    split_co IfaceCoercion
co' = ([], IfaceCoercion
co')

-- Why these three? See Note [Free TyVars and CoVars in IfaceType]
ppr_co PprPrec
_ (IfaceFreeCoVar TyVar
covar) = TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVar
covar
ppr_co PprPrec
_ (IfaceCoVarCo IfLclName
covar)   = IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
covar
ppr_co PprPrec
_ (IfaceHoleCo TyVar
covar)    = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVar
covar)

ppr_co PprPrec
_ (IfaceUnivCo UnivCoProvenance
prov Role
role IfaceType
ty1 IfaceType
ty2 [IfaceCoercion]
ds)
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Univ" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> (SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
      [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ Role -> SDoc
forall a. Outputable a => a -> SDoc
ppr Role
role SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> UnivCoProvenance -> SDoc
forall a. Outputable a => a -> SDoc
ppr UnivCoProvenance
prov SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> [IfaceCoercion] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [IfaceCoercion]
ds
          , SDoc
dcolon SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>  IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceType
ty2 ])

ppr_co PprPrec
ctxt_prec (IfaceInstCo IfaceCoercion
co IfaceCoercion
ty)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
appPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Inst" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [ IfaceCoercion -> SDoc
pprParendIfaceCoercion IfaceCoercion
co
                        , IfaceCoercion -> SDoc
pprParendIfaceCoercion IfaceCoercion
ty ]

ppr_co PprPrec
ctxt_prec (IfaceAxiomCo IfaceAxiomRule
ax [IfaceCoercion]
cos)
  | [IfaceCoercion] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [IfaceCoercion]
cos  = IfaceAxiomRule -> SDoc
pprIfAxRule IfaceAxiomRule
ax  -- Don't add parens
  | Bool
otherwise = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec (IfaceAxiomRule -> SDoc
pprIfAxRule IfaceAxiomRule
ax) [IfaceCoercion]
cos
ppr_co PprPrec
ctxt_prec (IfaceSymCo IfaceCoercion
co)
  = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Sym") [IfaceCoercion
co]
ppr_co PprPrec
ctxt_prec (IfaceTransCo IfaceCoercion
co1 IfaceCoercion
co2)
    -- chain nested TransCo
  = let ppr_trans :: IfaceCoercion -> [SDoc]
ppr_trans (IfaceTransCo IfaceCoercion
c1 IfaceCoercion
c2) = SDoc
forall doc. IsLine doc => doc
semi SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
topPrec IfaceCoercion
c1 SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: IfaceCoercion -> [SDoc]
ppr_trans IfaceCoercion
c2
        ppr_trans IfaceCoercion
c                    = [SDoc
forall doc. IsLine doc => doc
semi SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
opPrec IfaceCoercion
c]
    in PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
opPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
        [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat (PprPrec -> IfaceCoercion -> SDoc
ppr_co PprPrec
topPrec IfaceCoercion
co1 SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: IfaceCoercion -> [SDoc]
ppr_trans IfaceCoercion
co2)
ppr_co PprPrec
ctxt_prec (IfaceSelCo CoSel
d IfaceCoercion
co)
  = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"SelCo:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> CoSel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoSel
d) [IfaceCoercion
co]
ppr_co PprPrec
ctxt_prec (IfaceLRCo LeftOrRight
lr IfaceCoercion
co)
  = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec (LeftOrRight -> SDoc
forall a. Outputable a => a -> SDoc
ppr LeftOrRight
lr) [IfaceCoercion
co]
ppr_co PprPrec
ctxt_prec (IfaceSubCo IfaceCoercion
co)
  = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Sub") [IfaceCoercion
co]
ppr_co PprPrec
ctxt_prec (IfaceKindCo IfaceCoercion
co)
  = PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Kind") [IfaceCoercion
co]

ppr_special_co :: PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co :: PprPrec -> SDoc -> [IfaceCoercion] -> SDoc
ppr_special_co PprPrec
ctxt_prec SDoc
doc [IfaceCoercion]
cos
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
ctxt_prec PprPrec
appPrec
               ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep [SDoc
doc, Int -> SDoc -> SDoc
nest Int
4 ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
sep ((IfaceCoercion -> SDoc) -> [IfaceCoercion] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map IfaceCoercion -> SDoc
pprParendIfaceCoercion [IfaceCoercion]
cos))])

pprIfAxRule :: IfaceAxiomRule -> SDoc
pprIfAxRule :: IfaceAxiomRule -> SDoc
pprIfAxRule (IfaceAR_X IfLclName
n)   = IfLclName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfLclName
n
pprIfAxRule (IfaceAR_U IfExtName
n)   = IfExtName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfExtName
n
pprIfAxRule (IfaceAR_B IfExtName
n Int
i) = IfExtName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfExtName
n SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
brackets (Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
i)

ppr_role :: Role -> SDoc
ppr_role :: Role -> SDoc
ppr_role Role
r = SDoc
forall doc. IsLine doc => doc
underscore SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
pp_role
  where pp_role :: SDoc
pp_role = case Role
r of
                    Role
Nominal          -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'N'
                    Role
Representational -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'R'
                    Role
Phantom          -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'P'

-------------------
instance Outputable IfLclName where
  ppr :: IfLclName -> SDoc
ppr = FastString -> SDoc
forall a. Outputable a => a -> SDoc
ppr (FastString -> SDoc)
-> (IfLclName -> FastString) -> IfLclName -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IfLclName -> FastString
ifLclNameFS

instance Outputable IfaceTyCon where
  ppr :: IfaceTyCon -> SDoc
ppr = IfaceTyCon -> SDoc
pprIfaceTyCon

-- | Print an `IfaceTyCon` with a promotion tick if needed, without parens,
-- suitable for use in infix contexts
pprIfaceTyCon :: IfaceTyCon -> SDoc
pprIfaceTyCon :: IfaceTyCon -> SDoc
pprIfaceTyCon IfaceTyCon
tc = IfaceTyCon -> SDoc
pprPromotionQuote IfaceTyCon
tc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> IfExtName -> SDoc
forall a. Outputable a => a -> SDoc
ppr (IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc)

-- | Print an `IfaceTyCon` with a promotion tick if needed, possibly with parens,
-- suitable for use in prefix contexts
pprParendIfaceTyCon :: IfaceTyCon -> SDoc
pprParendIfaceTyCon :: IfaceTyCon -> SDoc
pprParendIfaceTyCon IfaceTyCon
tc = IfaceTyCon -> SDoc
pprPromotionQuote IfaceTyCon
tc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Bool -> SDoc -> SDoc
pprPrefixVar (OccName -> Bool
isSymOcc (IfExtName -> OccName
nameOccName IfExtName
tc_name)) (IfExtName -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfExtName
tc_name)
  where tc_name :: IfExtName
tc_name = IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc

instance Outputable IfaceTyConInfo where
  ppr :: IfaceTyConInfo -> SDoc
ppr (IfaceTyConInfo { ifaceTyConIsPromoted :: IfaceTyConInfo -> PromotionFlag
ifaceTyConIsPromoted = PromotionFlag
prom
                      , ifaceTyConSort :: IfaceTyConInfo -> IfaceTyConSort
ifaceTyConSort       = IfaceTyConSort
sort })
    = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
angleBrackets (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ PromotionFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr PromotionFlag
prom SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> IfaceTyConSort -> SDoc
forall a. Outputable a => a -> SDoc
ppr IfaceTyConSort
sort

pprPromotionQuote :: IfaceTyCon -> SDoc
pprPromotionQuote :: IfaceTyCon -> SDoc
pprPromotionQuote IfaceTyCon
tc =
  (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
sty ->
    let
      name :: OccName
name   = IfExtName -> OccName
forall a. NamedThing a => a -> OccName
getOccName (IfaceTyCon -> IfExtName
ifaceTyConName IfaceTyCon
tc)
      ticked :: Bool
ticked =
        case IfaceTyConInfo -> PromotionFlag
ifaceTyConIsPromoted (IfaceTyCon -> IfaceTyConInfo
ifaceTyConInfo IfaceTyCon
tc) of
          PromotionFlag
NotPromoted -> Bool
False
          PromotionFlag
IsPromoted  -> PprStyle -> QueryPromotionTick
promTick PprStyle
sty (OccName -> PromotedItem
PromotedItemDataCon OccName
name)
    in
      if Bool
ticked
      then Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'\''
      else SDoc
forall doc. IsOutput doc => doc
empty

pprPromotionQuoteI  :: PromotionFlag -> SDoc
pprPromotionQuoteI :: PromotionFlag -> SDoc
pprPromotionQuoteI PromotionFlag
NotPromoted = SDoc
forall doc. IsOutput doc => doc
empty
pprPromotionQuoteI PromotionFlag
IsPromoted  = Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'\''

instance Outputable IfaceCoercion where
  ppr :: IfaceCoercion -> SDoc
ppr = IfaceCoercion -> SDoc
pprIfaceCoercion

instance Binary IfaceTyCon where
  put_ :: WriteBinHandle -> IfaceTyCon -> IO ()
put_ WriteBinHandle
bh (IfaceTyCon IfExtName
n IfaceTyConInfo
i) = WriteBinHandle -> IfExtName -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfExtName
n IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> IfaceTyConInfo -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceTyConInfo
i

  get :: ReadBinHandle -> IO IfaceTyCon
get ReadBinHandle
bh = do
    n <- ReadBinHandle -> IO IfExtName
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
    i <- get bh
    return (IfaceTyCon n i)

instance Binary IfaceTyConSort where
   put_ :: WriteBinHandle -> IfaceTyConSort -> IO ()
put_ WriteBinHandle
bh IfaceTyConSort
IfaceNormalTyCon             = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
0
   put_ WriteBinHandle
bh (IfaceTupleTyCon Int
arity TupleSort
sort) = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> Int -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Int
arity IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> TupleSort -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh TupleSort
sort
   put_ WriteBinHandle
bh (IfaceSumTyCon Int
arity)        = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
2 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> Int -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Int
arity
   put_ WriteBinHandle
bh IfaceTyConSort
IfaceEqualityTyCon           = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
3

   get :: ReadBinHandle -> IO IfaceTyConSort
get ReadBinHandle
bh = do
       n <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
       case n of
         Word8
0 -> IfaceTyConSort -> IO IfaceTyConSort
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IfaceTyConSort
IfaceNormalTyCon
         Word8
1 -> Int -> TupleSort -> IfaceTyConSort
IfaceTupleTyCon (Int -> TupleSort -> IfaceTyConSort)
-> IO Int -> IO (TupleSort -> IfaceTyConSort)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBinHandle -> IO Int
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh IO (TupleSort -> IfaceTyConSort)
-> IO TupleSort -> IO IfaceTyConSort
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadBinHandle -> IO TupleSort
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
         Word8
2 -> Int -> IfaceTyConSort
IfaceSumTyCon (Int -> IfaceTyConSort) -> IO Int -> IO IfaceTyConSort
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadBinHandle -> IO Int
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
         Word8
_ -> IfaceTyConSort -> IO IfaceTyConSort
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IfaceTyConSort
IfaceEqualityTyCon

instance Binary IfaceTyConInfo where
   put_ :: WriteBinHandle -> IfaceTyConInfo -> IO ()
put_ WriteBinHandle
bh (IfaceTyConInfo PromotionFlag
i IfaceTyConSort
s) = WriteBinHandle -> PromotionFlag -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh PromotionFlag
i IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> IfaceTyConSort -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceTyConSort
s

   get :: ReadBinHandle -> IO IfaceTyConInfo
get ReadBinHandle
bh = PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
mkIfaceTyConInfo (PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo)
-> IO PromotionFlag -> IO (IfaceTyConSort -> IfaceTyConInfo)
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> ReadBinHandle -> IO PromotionFlag
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh IO (IfaceTyConSort -> IfaceTyConInfo)
-> IO IfaceTyConSort -> IO IfaceTyConInfo
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadBinHandle -> IO IfaceTyConSort
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
    -- We want to make sure, when reading from disk, as the most common case
    -- is supposed to be shared. Any thunk adds an additional indirection
    -- making sharing less useful.
    --
    -- See !12200 for how this bang and the one in 'IfaceTyCon' reduces the
    -- residency by ~10% when loading 'mi_extra_decls' from disk.

instance Outputable IfaceTyLit where
  ppr :: IfaceTyLit -> SDoc
ppr = IfaceTyLit -> SDoc
pprIfaceTyLit

instance Binary IfaceTyLit where
  put_ :: WriteBinHandle -> IfaceTyLit -> IO ()
put_ WriteBinHandle
bh (IfaceNumTyLit Integer
n)   = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> Integer -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Integer
n
  put_ WriteBinHandle
bh (IfaceStrTyLit LexicalFastString
n)   = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
2 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> LexicalFastString -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh LexicalFastString
n
  put_ WriteBinHandle
bh (IfaceCharTyLit Char
n)  = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
3 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> Char -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Char
n

  get :: ReadBinHandle -> IO IfaceTyLit
get ReadBinHandle
bh =
    do tag <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
       case tag of
         Word8
1 -> do { n <- ReadBinHandle -> IO Integer
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                 ; return (IfaceNumTyLit n) }
         Word8
2 -> do { n <- ReadBinHandle -> IO LexicalFastString
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                 ; return (IfaceStrTyLit n) }
         Word8
3 -> do { n <- ReadBinHandle -> IO Char
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                 ; return (IfaceCharTyLit n) }
         Word8
_ -> String -> IO IfaceTyLit
forall a. HasCallStack => String -> a
panic (String
"get IfaceTyLit " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
tag)

instance Binary IfaceAppArgs where
  put_ :: WriteBinHandle -> IfaceAppArgs -> IO ()
put_ WriteBinHandle
bh IfaceAppArgs
tk = do
    -- Int is variable length encoded so only
    -- one byte for small lists.
    WriteBinHandle -> Int -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh (IfaceAppArgs -> Int
ifaceAppArgsLength IfaceAppArgs
tk)
    IfaceAppArgs -> IO ()
go IfaceAppArgs
tk
    where
      go :: IfaceAppArgs -> IO ()
go IfaceAppArgs
IA_Nil = () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      go (IA_Arg IfaceType
a ForAllTyFlag
b IfaceAppArgs
t) = do
        WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
a
        WriteBinHandle -> ForAllTyFlag -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh ForAllTyFlag
b
        IfaceAppArgs -> IO ()
go IfaceAppArgs
t

  get :: ReadBinHandle -> IO IfaceAppArgs
get ReadBinHandle
bh = do
    n <- ReadBinHandle -> IO Int
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh :: IO Int
    go n
    where
      go :: Int -> IO IfaceAppArgs
go Int
0 = IfaceAppArgs -> IO IfaceAppArgs
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IfaceAppArgs
IA_Nil
      go Int
c = do
        a <- ReadBinHandle -> IO IfaceType
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
        b <- get bh
        IA_Arg a b <$> go (c - 1)

-------------------

-- Some notes about printing contexts
--
-- In the event that we are printing a singleton context (e.g. @Eq a@) we can
-- omit parentheses. However, we must take care to set the precedence correctly
-- to opPrec, since something like @a :~: b@ must be parenthesized (see
-- #9658).
--
-- When printing a larger context we use 'fsep' instead of 'sep' so that
-- the context doesn't get displayed as a giant column. Rather than,
--  instance (Eq a,
--            Eq b,
--            Eq c,
--            Eq d,
--            Eq e,
--            Eq f,
--            Eq g,
--            Eq h,
--            Eq i,
--            Eq j,
--            Eq k,
--            Eq l) =>
--           Eq (a, b, c, d, e, f, g, h, i, j, k, l)
--
-- we want
--
--  instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i,
--            Eq j, Eq k, Eq l) =>
--           Eq (a, b, c, d, e, f, g, h, i, j, k, l)



-- | Prints "(C a, D b) =>", including the arrow.
-- Used when we want to print a context in a type, so we
-- use 'funPrec' to decide whether to parenthesise a singleton
-- predicate; e.g.   Num a => a -> a
pprIfaceContextArr :: [IfacePredType] -> SDoc
pprIfaceContextArr :: [IfaceType] -> SDoc
pprIfaceContextArr []     = SDoc
forall doc. IsOutput doc => doc
empty
pprIfaceContextArr [IfaceType
pred] = PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
funPrec IfaceType
pred SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
darrow
pprIfaceContextArr [IfaceType]
preds  = [IfaceType] -> SDoc
ppr_parend_preds [IfaceType]
preds SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
darrow

-- | Prints a context or @()@ if empty
-- You give it the context precedence
pprIfaceContext :: PprPrec -> [IfacePredType] -> SDoc
pprIfaceContext :: PprPrec -> [IfaceType] -> SDoc
pprIfaceContext PprPrec
_    []     = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"()"
pprIfaceContext PprPrec
prec [IfaceType
pred] = PprPrec -> IfaceType -> SDoc
ppr_ty PprPrec
prec IfaceType
pred
pprIfaceContext PprPrec
_    [IfaceType]
preds  = [IfaceType] -> SDoc
ppr_parend_preds [IfaceType]
preds

ppr_parend_preds :: [IfacePredType] -> SDoc
ppr_parend_preds :: [IfaceType] -> SDoc
ppr_parend_preds [IfaceType]
preds = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
fsep (SDoc -> [SDoc] -> [SDoc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate SDoc
forall doc. IsLine doc => doc
comma ((IfaceType -> SDoc) -> [IfaceType] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map IfaceType -> SDoc
forall a. Outputable a => a -> SDoc
ppr [IfaceType]
preds)))

instance Binary IfaceType where
   put_ :: WriteBinHandle -> IfaceType -> IO ()
put_ WriteBinHandle
bh IfaceType
ty =
    case Proxy IfaceType -> WriteBinHandle -> BinaryWriter IfaceType
forall a. Typeable a => Proxy a -> WriteBinHandle -> BinaryWriter a
findUserDataWriter Proxy IfaceType
forall {k} (t :: k). Proxy t
Proxy WriteBinHandle
bh of
      BinaryWriter IfaceType
tbl -> BinaryWriter IfaceType -> WriteBinHandle -> IfaceType -> IO ()
forall s. BinaryWriter s -> WriteBinHandle -> s -> IO ()
putEntry BinaryWriter IfaceType
tbl WriteBinHandle
bh IfaceType
ty

   get :: ReadBinHandle -> IO IfaceType
get ReadBinHandle
bh = ReadBinHandle -> IO IfaceType
getIfaceTypeShared ReadBinHandle
bh

-- | This is the byte tag we expect to read when the next
-- value is not an 'IfaceType' value, but an offset into a
-- lookup table.
-- See Note [Deduplication during iface binary serialisation].
--
-- Must not overlap with any byte tag in 'getIfaceType'.
ifaceTypeSharedByte :: Word8
ifaceTypeSharedByte :: Word8
ifaceTypeSharedByte = Word8
99

-- | Like 'getIfaceType' but checks for a specific byte tag
-- that indicates that we won't be able to read a 'IfaceType' value
-- but rather an offset into a lookup table. Consequentially,
-- we look up the value for the 'IfaceType' in the look up table.
--
-- See Note [Deduplication during iface binary serialisation]
-- for details.
getIfaceTypeShared :: ReadBinHandle -> IO IfaceType
getIfaceTypeShared :: ReadBinHandle -> IO IfaceType
getIfaceTypeShared ReadBinHandle
bh = do
  start <- ReadBinHandle -> IO (Bin (ZonkAny 1))
forall {k} (a :: k). ReadBinHandle -> IO (Bin a)
tellBinReader ReadBinHandle
bh
  tag <- getByte bh
  if ifaceTypeSharedByte == tag
    then case findUserDataReader Proxy bh of
            BinaryReader IfaceType
tbl -> BinaryReader IfaceType -> ReadBinHandle -> IO IfaceType
forall s. BinaryReader s -> ReadBinHandle -> IO s
getEntry BinaryReader IfaceType
tbl ReadBinHandle
bh
    else seekBinReader bh start >> getIfaceType bh

-- | Serialises an 'IfaceType' to the given 'WriteBinHandle'.
--
-- Serialising inner 'IfaceType''s uses the 'Binary.put' of 'IfaceType' which may be using
-- a deduplication table. See Note [Deduplication during iface binary serialisation].
putIfaceType :: WriteBinHandle -> IfaceType -> IO ()
putIfaceType :: WriteBinHandle -> IfaceType -> IO ()
putIfaceType WriteBinHandle
_ (IfaceFreeTyVar TyVar
tv)
  = String -> SDoc -> IO ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Can't serialise IfaceFreeTyVar" (TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVar
tv)
  -- See Note [Free TyVars and CoVars in IfaceType]

putIfaceType WriteBinHandle
bh (IfaceForAllTy IfaceForAllBndr
aa IfaceType
ab) = do
        WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
0
        WriteBinHandle -> IfaceForAllBndr -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceForAllBndr
aa
        WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
ab
putIfaceType WriteBinHandle
bh (IfaceTyVar IfLclName
ad) = do
        WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1
        WriteBinHandle -> IfLclName -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfLclName
ad
putIfaceType WriteBinHandle
bh (IfaceAppTy IfaceType
ae IfaceAppArgs
af) = do
        WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
2
        WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
ae
        WriteBinHandle -> IfaceAppArgs -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceAppArgs
af
putIfaceType WriteBinHandle
bh (IfaceFunTy FunTyFlag
af IfaceType
aw IfaceType
ag IfaceType
ah) = do
        WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
3
        WriteBinHandle -> FunTyFlag -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh FunTyFlag
af
        WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
aw
        WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
ag
        WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
ah
putIfaceType WriteBinHandle
bh (IfaceTyConApp IfaceTyCon
tc IfaceAppArgs
tys)
  = do { WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
5; WriteBinHandle -> IfaceTyCon -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceTyCon
tc; WriteBinHandle -> IfaceAppArgs -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceAppArgs
tys }
putIfaceType WriteBinHandle
bh (IfaceCastTy IfaceType
a IfaceCoercion
b)
  = do { WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
6; WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
a; WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b }
putIfaceType WriteBinHandle
bh (IfaceCoercionTy IfaceCoercion
a)
  = do { WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
7; WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a }
putIfaceType WriteBinHandle
bh (IfaceTupleTy TupleSort
s PromotionFlag
i IfaceAppArgs
tys)
  = do { WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
8; WriteBinHandle -> TupleSort -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh TupleSort
s; WriteBinHandle -> PromotionFlag -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh PromotionFlag
i; WriteBinHandle -> IfaceAppArgs -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceAppArgs
tys }
putIfaceType WriteBinHandle
bh (IfaceLitTy IfaceTyLit
n)
  = do { WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
9; WriteBinHandle -> IfaceTyLit -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceTyLit
n }

-- | Deserialises an 'IfaceType' from the given 'ReadBinHandle'.
--
-- Reading inner 'IfaceType''s uses the 'Binary.get' of 'IfaceType' which may be using
-- a deduplication table. See Note [Deduplication during iface binary serialisation].
getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType
getIfaceType :: HasCallStack => ReadBinHandle -> IO IfaceType
getIfaceType ReadBinHandle
bh = do
            h <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
            case h of
              Word8
0 -> do aa <- ReadBinHandle -> IO IfaceForAllBndr
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      ab <- get bh
                      return (IfaceForAllTy aa ab)
              Word8
1 -> do ad <- ReadBinHandle -> IO IfLclName
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      return (IfaceTyVar ad)
              Word8
2 -> do ae <- ReadBinHandle -> IO IfaceType
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      af <- get bh
                      return (IfaceAppTy ae af)
              Word8
3 -> do af <- ReadBinHandle -> IO FunTyFlag
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      aw <- get bh
                      ag <- get bh
                      ah <- get bh
                      return (IfaceFunTy af aw ag ah)
              Word8
5 -> do { tc <- ReadBinHandle -> IO IfaceTyCon
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; tys <- get bh
                      ; return (IfaceTyConApp tc tys) }
              Word8
6 -> do { a <- ReadBinHandle -> IO IfaceType
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; b <- get bh
                      ; return (IfaceCastTy a b) }
              Word8
7 -> do { a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                      ; return (IfaceCoercionTy a) }

              Word8
8 -> do { s <- ReadBinHandle -> IO TupleSort
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; i <- get bh; tys <- get bh
                      ; return (IfaceTupleTy s i tys) }
              Word8
_  -> do n <- ReadBinHandle -> IO IfaceTyLit
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                       return (IfaceLitTy n)

instance Binary IfLclName where
  put_ :: WriteBinHandle -> IfLclName -> IO ()
put_ WriteBinHandle
bh = WriteBinHandle -> FastString -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh (FastString -> IO ())
-> (IfLclName -> FastString) -> IfLclName -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IfLclName -> FastString
ifLclNameFS

  get :: ReadBinHandle -> IO IfLclName
get ReadBinHandle
bh = do
    fs <- ReadBinHandle -> IO FastString
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
    pure $ IfLclName $ LexicalFastString fs

instance Binary IfaceMCoercion where
  put_ :: WriteBinHandle -> IfaceMCoercion -> IO ()
put_ WriteBinHandle
bh IfaceMCoercion
IfaceMRefl =
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1
  put_ WriteBinHandle
bh (IfaceMCo IfaceCoercion
co) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
2
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
co

  get :: ReadBinHandle -> IO IfaceMCoercion
get ReadBinHandle
bh = do
    tag <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
    case tag of
         Word8
1 -> IfaceMCoercion -> IO IfaceMCoercion
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IfaceMCoercion
IfaceMRefl
         Word8
2 -> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                 return $ IfaceMCo a
         Word8
_ -> String -> IO IfaceMCoercion
forall a. HasCallStack => String -> a
panic (String
"get IfaceMCoercion " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
tag)

instance Binary IfaceCoercion where
  put_ :: WriteBinHandle -> IfaceCoercion -> IO ()
put_ WriteBinHandle
bh (IfaceReflCo IfaceType
a) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1
          WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
a
  put_ WriteBinHandle
bh (IfaceGReflCo Role
a IfaceType
b IfaceMCoercion
c) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
2
          WriteBinHandle -> Role -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Role
a
          WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
b
          WriteBinHandle -> IfaceMCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceMCoercion
c
  put_ WriteBinHandle
bh (IfaceFunCo Role
a IfaceCoercion
w IfaceCoercion
b IfaceCoercion
c) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
3
          WriteBinHandle -> Role -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Role
a
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
w
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
c
  put_ WriteBinHandle
bh (IfaceTyConAppCo Role
a IfaceTyCon
b [IfaceCoercion]
c) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
4
          WriteBinHandle -> Role -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Role
a
          WriteBinHandle -> IfaceTyCon -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceTyCon
b
          WriteBinHandle -> [IfaceCoercion] -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh [IfaceCoercion]
c
  put_ WriteBinHandle
bh (IfaceAppCo IfaceCoercion
a IfaceCoercion
b) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
5
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
  put_ WriteBinHandle
bh (IfaceForAllCo IfaceBndr
a ForAllTyFlag
visL ForAllTyFlag
visR IfaceCoercion
b IfaceCoercion
c) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
6
          WriteBinHandle -> IfaceBndr -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceBndr
a
          WriteBinHandle -> ForAllTyFlag -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh ForAllTyFlag
visL
          WriteBinHandle -> ForAllTyFlag -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh ForAllTyFlag
visR
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
c
  put_ WriteBinHandle
bh (IfaceCoVarCo IfLclName
a) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
7
          WriteBinHandle -> IfLclName -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfLclName
a
  put_ WriteBinHandle
bh (IfaceUnivCo UnivCoProvenance
a Role
b IfaceType
c IfaceType
d [IfaceCoercion]
deps) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
9
          WriteBinHandle -> UnivCoProvenance -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh UnivCoProvenance
a
          WriteBinHandle -> Role -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Role
b
          WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
c
          WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
d
          WriteBinHandle -> [IfaceCoercion] -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh [IfaceCoercion]
deps
  put_ WriteBinHandle
bh (IfaceSymCo IfaceCoercion
a) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
10
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a
  put_ WriteBinHandle
bh (IfaceTransCo IfaceCoercion
a IfaceCoercion
b) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
11
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
  put_ WriteBinHandle
bh (IfaceSelCo CoSel
a IfaceCoercion
b) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
12
          WriteBinHandle -> CoSel -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh CoSel
a
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
  put_ WriteBinHandle
bh (IfaceLRCo LeftOrRight
a IfaceCoercion
b) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
13
          WriteBinHandle -> LeftOrRight -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh LeftOrRight
a
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
  put_ WriteBinHandle
bh (IfaceInstCo IfaceCoercion
a IfaceCoercion
b) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
14
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
b
  put_ WriteBinHandle
bh (IfaceKindCo IfaceCoercion
a) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
15
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a
  put_ WriteBinHandle
bh (IfaceSubCo IfaceCoercion
a) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
16
          WriteBinHandle -> IfaceCoercion -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceCoercion
a
  put_ WriteBinHandle
bh (IfaceAxiomCo IfaceAxiomRule
a [IfaceCoercion]
b) = do
          WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
17
          WriteBinHandle -> IfaceAxiomRule -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceAxiomRule
a
          WriteBinHandle -> [IfaceCoercion] -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh [IfaceCoercion]
b
  put_ WriteBinHandle
_ (IfaceFreeCoVar TyVar
cv)
       = String -> SDoc -> IO ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Can't serialise IfaceFreeCoVar" (TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVar
cv)
           -- See Note [Free TyVars and CoVars in IfaceType]
  put_ WriteBinHandle
_  (IfaceHoleCo TyVar
cv)
       = String -> SDoc -> IO ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Can't serialise IfaceHoleCo" (TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVar
cv)
           -- See Note [Holes in IfaceCoercion]

  get :: ReadBinHandle -> IO IfaceCoercion
get ReadBinHandle
bh = do
      tag <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
      case tag of
           Word8
1 -> do a <- ReadBinHandle -> IO IfaceType
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   return $ IfaceReflCo a
           Word8
2 -> do a <- ReadBinHandle -> IO Role
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   c <- get bh
                   return $ IfaceGReflCo a b c
           Word8
3 -> do a  <- ReadBinHandle -> IO Role
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   w  <- get bh
                   b  <- get bh
                   c  <- get bh
                   return $ IfaceFunCo a w b c
           Word8
4 -> do a <- ReadBinHandle -> IO Role
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   c <- get bh
                   return $ IfaceTyConAppCo a b c
           Word8
5 -> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   return $ IfaceAppCo a b
           Word8
6 -> do a <- ReadBinHandle -> IO IfaceBndr
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   visL <- get bh
                   visR <- get bh
                   b <- get bh
                   c <- get bh
                   return $ IfaceForAllCo a visL visR b c
           Word8
7 -> do a <- ReadBinHandle -> IO IfLclName
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   return $ IfaceCoVarCo a
           Word8
9 -> do a <- ReadBinHandle -> IO UnivCoProvenance
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   c <- get bh
                   d <- get bh
                   deps <- get bh
                   return $ IfaceUnivCo a b c d deps
           Word8
10-> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   return $ IfaceSymCo a
           Word8
11-> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   return $ IfaceTransCo a b
           Word8
12-> do a <- ReadBinHandle -> IO CoSel
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   return $ IfaceSelCo a b
           Word8
13-> do a <- ReadBinHandle -> IO LeftOrRight
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   return $ IfaceLRCo a b
           Word8
14-> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   return $ IfaceInstCo a b
           Word8
15-> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   return $ IfaceKindCo a
           Word8
16-> do a <- ReadBinHandle -> IO IfaceCoercion
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   return $ IfaceSubCo a
           Word8
17-> do a <- ReadBinHandle -> IO IfaceAxiomRule
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh
                   b <- get bh
                   return $ IfaceAxiomCo a b
           Word8
_ -> String -> IO IfaceCoercion
forall a. HasCallStack => String -> a
panic (String
"get IfaceCoercion " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
tag)

instance Binary IfaceAxiomRule where
  put_ :: WriteBinHandle -> IfaceAxiomRule -> IO ()
put_ WriteBinHandle
bh (IfaceAR_X IfLclName
n)   = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
0 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> IfLclName -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfLclName
n
  put_ WriteBinHandle
bh (IfaceAR_U IfExtName
n)   = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> IfExtName -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfExtName
n
  put_ WriteBinHandle
bh (IfaceAR_B IfExtName
n Int
i) = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
2 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> IfExtName -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfExtName
n IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> Int -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh Int
i

  get :: ReadBinHandle -> IO IfaceAxiomRule
get ReadBinHandle
bh = do h <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
              case h of
                Word8
0 -> do { n <- ReadBinHandle -> IO IfLclName
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; return (IfaceAR_X n) }
                Word8
1 -> do { n <- ReadBinHandle -> IO IfExtName
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; return (IfaceAR_U n) }
                Word8
_ -> do { n <- ReadBinHandle -> IO IfExtName
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; i <- get bh; return (IfaceAR_B n i) }

instance Binary (DefMethSpec IfaceType) where
    put_ :: WriteBinHandle -> DefMethSpec IfaceType -> IO ()
put_ WriteBinHandle
bh DefMethSpec IfaceType
VanillaDM     = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
0
    put_ WriteBinHandle
bh (GenericDM IfaceType
t) = WriteBinHandle -> Word8 -> IO ()
putByte WriteBinHandle
bh Word8
1 IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriteBinHandle -> IfaceType -> IO ()
forall a. Binary a => WriteBinHandle -> a -> IO ()
put_ WriteBinHandle
bh IfaceType
t
    get :: ReadBinHandle -> IO (DefMethSpec IfaceType)
get ReadBinHandle
bh = do
            h <- ReadBinHandle -> IO Word8
getByte ReadBinHandle
bh
            case h of
              Word8
0 -> DefMethSpec IfaceType -> IO (DefMethSpec IfaceType)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return DefMethSpec IfaceType
forall ty. DefMethSpec ty
VanillaDM
              Word8
_ -> do { t <- ReadBinHandle -> IO IfaceType
forall a. Binary a => ReadBinHandle -> IO a
get ReadBinHandle
bh; return (GenericDM t) }

instance NFData IfaceType where
  rnf :: IfaceType -> ()
rnf = \case
    IfaceFreeTyVar TyVar
f1 -> TyVar
f1 TyVar -> () -> ()
forall a b. a -> b -> b
`seq` ()
    IfaceTyVar IfLclName
f1 -> IfLclName -> ()
forall a. NFData a => a -> ()
rnf IfLclName
f1
    IfaceLitTy IfaceTyLit
f1 -> IfaceTyLit -> ()
forall a. NFData a => a -> ()
rnf IfaceTyLit
f1
    IfaceAppTy IfaceType
f1 IfaceAppArgs
f2 -> IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceAppArgs -> ()
forall a. NFData a => a -> ()
rnf IfaceAppArgs
f2
    IfaceFunTy FunTyFlag
f1 IfaceType
f2 IfaceType
f3 IfaceType
f4 -> FunTyFlag
f1 FunTyFlag -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f2 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f3 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f4
    IfaceForAllTy IfaceForAllBndr
f1 IfaceType
f2 -> IfaceForAllBndr
f1 IfaceForAllBndr -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f2
    IfaceTyConApp IfaceTyCon
f1 IfaceAppArgs
f2 -> IfaceTyCon -> ()
forall a. NFData a => a -> ()
rnf IfaceTyCon
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceAppArgs -> ()
forall a. NFData a => a -> ()
rnf IfaceAppArgs
f2
    IfaceCastTy IfaceType
f1 IfaceCoercion
f2 -> IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2
    IfaceCoercionTy IfaceCoercion
f1 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1
    IfaceTupleTy TupleSort
f1 PromotionFlag
f2 IfaceAppArgs
f3 -> TupleSort
f1 TupleSort -> () -> ()
forall a b. a -> b -> b
`seq` PromotionFlag
f2 PromotionFlag -> () -> ()
forall a b. a -> b -> b
`seq` IfaceAppArgs -> ()
forall a. NFData a => a -> ()
rnf IfaceAppArgs
f3

instance NFData IfaceTyLit where
  rnf :: IfaceTyLit -> ()
rnf = \case
    IfaceNumTyLit Integer
f1 -> Integer -> ()
forall a. NFData a => a -> ()
rnf Integer
f1
    IfaceStrTyLit LexicalFastString
f1 -> LexicalFastString -> ()
forall a. NFData a => a -> ()
rnf LexicalFastString
f1
    IfaceCharTyLit Char
f1 -> Char -> ()
forall a. NFData a => a -> ()
rnf Char
f1

instance NFData IfaceCoercion where
  rnf :: IfaceCoercion -> ()
rnf = \case
    IfaceReflCo IfaceType
f1 -> IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f1
    IfaceGReflCo Role
f1 IfaceType
f2 IfaceMCoercion
f3 -> Role
f1 Role -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f2 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceMCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceMCoercion
f3
    IfaceFunCo Role
f1 IfaceCoercion
f2 IfaceCoercion
f3 IfaceCoercion
f4 -> Role
f1 Role -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f3 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f4
    IfaceTyConAppCo Role
f1 IfaceTyCon
f2 [IfaceCoercion]
f3 -> Role
f1 Role -> () -> ()
forall a b. a -> b -> b
`seq` IfaceTyCon -> ()
forall a. NFData a => a -> ()
rnf IfaceTyCon
f2 () -> () -> ()
forall a b. a -> b -> b
`seq` [IfaceCoercion] -> ()
forall a. NFData a => a -> ()
rnf [IfaceCoercion]
f3
    IfaceAppCo IfaceCoercion
f1 IfaceCoercion
f2 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2
    IfaceForAllCo IfaceBndr
f1 ForAllTyFlag
f2 ForAllTyFlag
f3 IfaceCoercion
f4 IfaceCoercion
f5 -> IfaceBndr -> ()
forall a. NFData a => a -> ()
rnf IfaceBndr
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` ForAllTyFlag -> ()
forall a. NFData a => a -> ()
rnf ForAllTyFlag
f2 () -> () -> ()
forall a b. a -> b -> b
`seq` ForAllTyFlag -> ()
forall a. NFData a => a -> ()
rnf ForAllTyFlag
f3 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f4 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f5
    IfaceCoVarCo IfLclName
f1 -> IfLclName -> ()
forall a. NFData a => a -> ()
rnf IfLclName
f1
    IfaceAxiomCo IfaceAxiomRule
f1 [IfaceCoercion]
f2 -> IfaceAxiomRule -> ()
forall a. NFData a => a -> ()
rnf IfaceAxiomRule
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` [IfaceCoercion] -> ()
forall a. NFData a => a -> ()
rnf [IfaceCoercion]
f2
    IfaceUnivCo UnivCoProvenance
f1 Role
f2 IfaceType
f3 IfaceType
f4 [IfaceCoercion]
deps -> UnivCoProvenance -> ()
forall a. NFData a => a -> ()
rnf UnivCoProvenance
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` Role
f2 Role -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f3 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f4 () -> () -> ()
forall a b. a -> b -> b
`seq` [IfaceCoercion] -> ()
forall a. NFData a => a -> ()
rnf [IfaceCoercion]
deps
    IfaceSymCo IfaceCoercion
f1 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1
    IfaceTransCo IfaceCoercion
f1 IfaceCoercion
f2 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2
    IfaceSelCo CoSel
f1 IfaceCoercion
f2 -> CoSel -> ()
forall a. NFData a => a -> ()
rnf CoSel
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2
    IfaceLRCo LeftOrRight
f1 IfaceCoercion
f2 -> LeftOrRight
f1 LeftOrRight -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2
    IfaceInstCo IfaceCoercion
f1 IfaceCoercion
f2 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f2
    IfaceKindCo IfaceCoercion
f1 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1
    IfaceSubCo IfaceCoercion
f1 -> IfaceCoercion -> ()
forall a. NFData a => a -> ()
rnf IfaceCoercion
f1
    IfaceFreeCoVar TyVar
f1 -> TyVar
f1 TyVar -> () -> ()
forall a b. a -> b -> b
`seq` ()
    IfaceHoleCo TyVar
f1 -> TyVar
f1 TyVar -> () -> ()
forall a b. a -> b -> b
`seq` ()

instance NFData IfaceAxiomRule where
  rnf :: IfaceAxiomRule -> ()
rnf = \case
    IfaceAR_X IfLclName
n   -> IfLclName -> ()
forall a. NFData a => a -> ()
rnf IfLclName
n
    IfaceAR_U IfExtName
n   -> IfExtName -> ()
forall a. NFData a => a -> ()
rnf IfExtName
n
    IfaceAR_B IfExtName
n Int
i -> IfExtName -> ()
forall a. NFData a => a -> ()
rnf IfExtName
n () -> () -> ()
forall a b. a -> b -> b
`seq` Int -> ()
forall a. NFData a => a -> ()
rnf Int
i

instance NFData IfaceMCoercion where
  rnf :: IfaceMCoercion -> ()
rnf IfaceMCoercion
x = IfaceMCoercion -> () -> ()
forall a b. a -> b -> b
seq IfaceMCoercion
x ()

instance NFData IfaceOneShot where
  rnf :: IfaceOneShot -> ()
rnf IfaceOneShot
x = IfaceOneShot -> () -> ()
forall a b. a -> b -> b
seq IfaceOneShot
x ()

instance NFData IfaceTyConSort where
  rnf :: IfaceTyConSort -> ()
rnf = \case
    IfaceTyConSort
IfaceNormalTyCon -> ()
    IfaceTupleTyCon Int
arity TupleSort
sort -> Int -> ()
forall a. NFData a => a -> ()
rnf Int
arity () -> () -> ()
forall a b. a -> b -> b
`seq` TupleSort
sort TupleSort -> () -> ()
forall a b. a -> b -> b
`seq` ()
    IfaceSumTyCon Int
arity -> Int -> ()
forall a. NFData a => a -> ()
rnf Int
arity
    IfaceTyConSort
IfaceEqualityTyCon -> ()

instance NFData IfLclName where
  rnf :: IfLclName -> ()
rnf (IfLclName LexicalFastString
lfs) = LexicalFastString -> ()
forall a. NFData a => a -> ()
rnf LexicalFastString
lfs

instance NFData IfaceTyConInfo where
  rnf :: IfaceTyConInfo -> ()
rnf (IfaceTyConInfo PromotionFlag
f IfaceTyConSort
s) = PromotionFlag
f PromotionFlag -> () -> ()
forall a b. a -> b -> b
`seq` IfaceTyConSort -> ()
forall a. NFData a => a -> ()
rnf IfaceTyConSort
s

instance NFData IfaceTyCon where
  rnf :: IfaceTyCon -> ()
rnf (IfaceTyCon IfExtName
nm IfaceTyConInfo
info) = IfExtName -> ()
forall a. NFData a => a -> ()
rnf IfExtName
nm () -> () -> ()
forall a b. a -> b -> b
`seq` IfaceTyConInfo -> ()
forall a. NFData a => a -> ()
rnf IfaceTyConInfo
info

instance NFData IfaceBndr where
  rnf :: IfaceBndr -> ()
rnf = \case
    IfaceIdBndr IfaceIdBndr
id_bndr -> IfaceIdBndr -> ()
forall a. NFData a => a -> ()
rnf IfaceIdBndr
id_bndr
    IfaceTvBndr IfaceTvBndr
tv_bndr -> IfaceTvBndr -> ()
forall a. NFData a => a -> ()
rnf IfaceTvBndr
tv_bndr

instance NFData IfaceAppArgs where
  rnf :: IfaceAppArgs -> ()
rnf = \case
    IfaceAppArgs
IA_Nil -> ()
    IA_Arg IfaceType
f1 ForAllTyFlag
f2 IfaceAppArgs
f3 -> IfaceType -> ()
forall a. NFData a => a -> ()
rnf IfaceType
f1 () -> () -> ()
forall a b. a -> b -> b
`seq` ForAllTyFlag
f2 ForAllTyFlag -> () -> ()
forall a b. a -> b -> b
`seq` IfaceAppArgs -> ()
forall a. NFData a => a -> ()
rnf IfaceAppArgs
f3