{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1998
\section[TyCoRep]{Type and Coercion - friends' interface}

Note [The Type-related module hierarchy]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Class
  CoAxiom
  TyCon    imports Class, CoAxiom
  TyCoRep  imports Class, CoAxiom, TyCon
  TysPrim  imports TyCoRep ( including mkTyConTy )
  Kind     imports TysPrim ( mainly for primitive kinds )
  Type     imports Kind
  Coercion imports Type
-}

-- We expose the relevant stuff from this module via the Type module
{-# OPTIONS_HADDOCK not-home #-}
{-# LANGUAGE CPP, DeriveDataTypeable, MultiWayIf #-}

module TyCoRep (
        TyThing(..), tyThingCategory, pprTyThingCategory, pprShortTyThing,

        -- * Types
        Type(..),
        TyLit(..),
        KindOrType, Kind,
        KnotTied,
        PredType, ThetaType,      -- Synonyms
        ArgFlag(..),

        -- * Coercions
        Coercion(..),
        UnivCoProvenance(..),
        CoercionHole(..), coHoleCoVar, setCoHoleCoVar,
        CoercionN, CoercionR, CoercionP, KindCoercion,
        MCoercion(..), MCoercionR, MCoercionN,

        -- * Functions over types
        mkTyConTy, mkTyVarTy, mkTyVarTys,
        mkTyCoVarTy, mkTyCoVarTys,
        mkFunTy, mkFunTys, mkTyCoForAllTy, mkForAllTys,
        mkForAllTy,
        mkTyCoPiTy, mkTyCoPiTys,
        mkPiTys,

        kindRep_maybe, kindRep,
        isLiftedTypeKind, isUnliftedTypeKind,
        isLiftedRuntimeRep, isUnliftedRuntimeRep,
        isRuntimeRepTy, isRuntimeRepVar,
        sameVis,

        -- * Functions over binders
        TyCoBinder(..), TyCoVarBinder, TyBinder,
        binderVar, binderVars, binderType, binderArgFlag,
        delBinderVar,
        isInvisibleArgFlag, isVisibleArgFlag,
        isInvisibleBinder, isVisibleBinder,
        isTyBinder, isNamedBinder,
        tyCoBinderArgFlag,

        -- * Functions over coercions
        pickLR,

        -- * Pretty-printing
        pprType, pprParendType, pprPrecType, pprPrecTypeX,
        pprTypeApp, pprTCvBndr, pprTCvBndrs,
        pprSigmaType,
        pprTheta, pprParendTheta, pprForAll, pprUserForAll,
        pprTyVar, pprTyVars,
        pprThetaArrowTy, pprClassPred,
        pprKind, pprParendKind, pprTyLit,
        PprPrec(..), topPrec, sigPrec, opPrec, funPrec, appPrec, maybeParen,
        pprDataCons, pprWithExplicitKindsWhen,

        pprCo, pprParendCo,

        debugPprType,

        -- * Free variables
        tyCoVarsOfType, tyCoVarsOfTypeDSet, tyCoVarsOfTypes, tyCoVarsOfTypesDSet,
        tyCoFVsBndr, tyCoFVsVarBndr, tyCoFVsVarBndrs,
        tyCoFVsOfType, tyCoVarsOfTypeList,
        tyCoFVsOfTypes, tyCoVarsOfTypesList,
        coVarsOfType, coVarsOfTypes,
        coVarsOfCo, coVarsOfCos,
        tyCoVarsOfCo, tyCoVarsOfCos,
        tyCoVarsOfCoDSet,
        tyCoFVsOfCo, tyCoFVsOfCos,
        tyCoVarsOfCoList, tyCoVarsOfProv,
        almostDevoidCoVarOfCo,
        injectiveVarsOfBinder, injectiveVarsOfType,

        noFreeVarsOfType, noFreeVarsOfCo,

        -- * Substitutions
        TCvSubst(..), TvSubstEnv, CvSubstEnv,
        emptyTvSubstEnv, emptyCvSubstEnv, composeTCvSubstEnv, composeTCvSubst,
        emptyTCvSubst, mkEmptyTCvSubst, isEmptyTCvSubst,
        mkTCvSubst, mkTvSubst, mkCvSubst,
        getTvSubstEnv,
        getCvSubstEnv, getTCvInScope, getTCvSubstRangeFVs,
        isInScope, notElemTCvSubst,
        setTvSubstEnv, setCvSubstEnv, zapTCvSubst,
        extendTCvInScope, extendTCvInScopeList, extendTCvInScopeSet,
        extendTCvSubst, extendTCvSubstWithClone,
        extendCvSubst, extendCvSubstWithClone,
        extendTvSubst, extendTvSubstBinderAndInScope, extendTvSubstWithClone,
        extendTvSubstList, extendTvSubstAndInScope,
        extendTCvSubstList,
        unionTCvSubst, zipTyEnv, zipCoEnv, mkTyCoInScopeSet,
        zipTvSubst, zipCvSubst,
        zipTCvSubst,
        mkTvSubstPrs,

        substTyWith, substTyWithCoVars, substTysWith, substTysWithCoVars,
        substCoWith,
        substTy, substTyAddInScope,
        substTyUnchecked, substTysUnchecked, substThetaUnchecked,
        substTyWithUnchecked,
        substCoUnchecked, substCoWithUnchecked,
        substTyWithInScope,
        substTys, substTheta,
        lookupTyVar,
        substCo, substCos, substCoVar, substCoVars, lookupCoVar,
        cloneTyVarBndr, cloneTyVarBndrs,
        substVarBndr, substVarBndrs,
        substTyVarBndr, substTyVarBndrs,
        substCoVarBndr,
        substTyVar, substTyVars, substTyCoVars,
        substForAllCoBndr,
        substVarBndrUsing, substForAllCoBndrUsing,
        checkValidSubst, isValidTCvSubst,

        -- * Tidying type related things up for printing
        tidyType,      tidyTypes,
        tidyOpenType,  tidyOpenTypes,
        tidyOpenKind,
        tidyVarBndr, tidyVarBndrs, tidyFreeTyCoVars, avoidNameClashes,
        tidyOpenTyCoVar, tidyOpenTyCoVars,
        tidyTyCoVarOcc,
        tidyTopType,
        tidyKind,
        tidyCo, tidyCos,
        tidyTyCoVarBinder, tidyTyCoVarBinders,

        -- * Sizes
        typeSize, coercionSize, provSize
    ) where

#include "GhclibHsVersions.h"

import GhcPrelude

import {-# SOURCE #-} DataCon( dataConFullSig
                             , dataConUserTyVarBinders
                             , DataCon )
import {-# SOURCE #-} Type( isPredTy, isCoercionTy, mkAppTy, mkCastTy
                          , tyCoVarsOfTypeWellScoped
                          , tyCoVarsOfTypesWellScoped
                          , scopedSort
                          , coreView )
   -- Transitively pulls in a LOT of stuff, better to break the loop

import {-# SOURCE #-} Coercion
import {-# SOURCE #-} ConLike ( ConLike(..), conLikeName )
import {-# SOURCE #-} ToIface( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndr
                             , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercionX )

-- friends:
import IfaceType
import Var
import VarEnv
import VarSet
import Name hiding ( varName )
import TyCon
import Class
import CoAxiom
import FV

-- others
import BasicTypes ( LeftOrRight(..), PprPrec(..), topPrec, sigPrec, opPrec
                  , funPrec, appPrec, maybeParen, pickLR )
import PrelNames
import Outputable
import DynFlags
import FastString
import Pair
import UniqSupply
import Util
import UniqFM
import UniqSet

-- libraries
import qualified Data.Data as Data hiding ( TyCon )
import Data.List
import Data.IORef ( IORef )   -- for CoercionHole

{-
%************************************************************************
%*                                                                      *
                        TyThing
%*                                                                      *
%************************************************************************

Despite the fact that DataCon has to be imported via a hi-boot route,
this module seems the right place for TyThing, because it's needed for
funTyCon and all the types in TysPrim.

It is also SOURCE-imported into Name.hs


Note [ATyCon for classes]
~~~~~~~~~~~~~~~~~~~~~~~~~
Both classes and type constructors are represented in the type environment
as ATyCon.  You can tell the difference, and get to the class, with
   isClassTyCon :: TyCon -> Bool
   tyConClass_maybe :: TyCon -> Maybe Class
The Class and its associated TyCon have the same Name.
-}

-- | A global typecheckable-thing, essentially anything that has a name.
-- Not to be confused with a 'TcTyThing', which is also a typecheckable
-- thing but in the *local* context.  See 'TcEnv' for how to retrieve
-- a 'TyThing' given a 'Name'.
data TyThing
  = AnId     Id
  | AConLike ConLike
  | ATyCon   TyCon       -- TyCons and classes; see Note [ATyCon for classes]
  | ACoAxiom (CoAxiom Branched)

instance Outputable TyThing where
  ppr :: TyThing -> SDoc
ppr = TyThing -> SDoc
pprShortTyThing

instance NamedThing TyThing where       -- Can't put this with the type
  getName :: TyThing -> Name
getName (AnId Id
id)     = Id -> Name
forall a. NamedThing a => a -> Name
getName Id
id    -- decl, because the DataCon instance
  getName (ATyCon TyCon
tc)   = TyCon -> Name
forall a. NamedThing a => a -> Name
getName TyCon
tc    -- isn't visible there
  getName (ACoAxiom CoAxiom Branched
cc) = CoAxiom Branched -> Name
forall a. NamedThing a => a -> Name
getName CoAxiom Branched
cc
  getName (AConLike ConLike
cl) = ConLike -> Name
conLikeName ConLike
cl

pprShortTyThing :: TyThing -> SDoc
-- c.f. PprTyThing.pprTyThing, which prints all the details
pprShortTyThing :: TyThing -> SDoc
pprShortTyThing TyThing
thing
  = TyThing -> SDoc
pprTyThingCategory TyThing
thing SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyThing -> Name
forall a. NamedThing a => a -> Name
getName TyThing
thing))

pprTyThingCategory :: TyThing -> SDoc
pprTyThingCategory :: TyThing -> SDoc
pprTyThingCategory = String -> SDoc
text (String -> SDoc) -> (TyThing -> String) -> TyThing -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
capitalise (String -> String) -> (TyThing -> String) -> TyThing -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyThing -> String
tyThingCategory

tyThingCategory :: TyThing -> String
tyThingCategory :: TyThing -> String
tyThingCategory (ATyCon TyCon
tc)
  | TyCon -> Bool
isClassTyCon TyCon
tc = String
"class"
  | Bool
otherwise       = String
"type constructor"
tyThingCategory (ACoAxiom CoAxiom Branched
_) = String
"coercion axiom"
tyThingCategory (AnId   Id
_)   = String
"identifier"
tyThingCategory (AConLike (RealDataCon DataCon
_)) = String
"data constructor"
tyThingCategory (AConLike (PatSynCon PatSyn
_))  = String
"pattern synonym"


{- **********************************************************************
*                                                                       *
                        Type
*                                                                       *
********************************************************************** -}

-- | The key representation of types within the compiler

type KindOrType = Type -- See Note [Arguments to type constructors]

-- | The key type representing kinds in the compiler.
type Kind = Type

-- If you edit this type, you may need to update the GHC formalism
-- See Note [GHC Formalism] in coreSyn/CoreLint.hs
data Type
  -- See Note [Non-trivial definitional equality]
  = TyVarTy Var -- ^ Vanilla type or kind variable (*never* a coercion variable)

  | AppTy
        Type
        Type            -- ^ Type application to something other than a 'TyCon'. Parameters:
                        --
                        --  1) Function: must /not/ be a 'TyConApp' or 'CastTy',
                        --     must be another 'AppTy', or 'TyVarTy'
                        --     See Note [Respecting definitional equality] (EQ1) about the
                        --     no 'CastTy' requirement
                        --
                        --  2) Argument type

  | TyConApp
        TyCon
        [KindOrType]    -- ^ Application of a 'TyCon', including newtypes /and/ synonyms.
                        -- Invariant: saturated applications of 'FunTyCon' must
                        -- use 'FunTy' and saturated synonyms must use their own
                        -- constructors. However, /unsaturated/ 'FunTyCon's
                        -- do appear as 'TyConApp's.
                        -- Parameters:
                        --
                        -- 1) Type constructor being applied to.
                        --
                        -- 2) Type arguments. Might not have enough type arguments
                        --    here to saturate the constructor.
                        --    Even type synonyms are not necessarily saturated;
                        --    for example unsaturated type synonyms
                        --    can appear as the right hand side of a type synonym.

  | ForAllTy
        {-# UNPACK #-} !TyCoVarBinder
        Type            -- ^ A Π type.

  | FunTy Type Type     -- ^ t1 -> t2   Very common, so an important special case

  | LitTy TyLit     -- ^ Type literals are similar to type constructors.

  | CastTy
        Type
        KindCoercion  -- ^ A kind cast. The coercion is always nominal.
                      -- INVARIANT: The cast is never refl.
                      -- INVARIANT: The Type is not a CastTy (use TransCo instead)
                      -- See Note [Respecting definitional equality] (EQ2) and (EQ3)

  | CoercionTy
        Coercion    -- ^ Injection of a Coercion into a type
                    -- This should only ever be used in the RHS of an AppTy,
                    -- in the list of a TyConApp, when applying a promoted
                    -- GADT data constructor

  deriving Typeable Type
DataType
Constr
Typeable Type
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Type -> c Type)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Type)
-> (Type -> Constr)
-> (Type -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Type))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Type))
-> ((forall b. Data b => b -> b) -> Type -> Type)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r)
-> (forall u. (forall d. Data d => d -> u) -> Type -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Type -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Type -> m Type)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Type -> m Type)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Type -> m Type)
-> Data Type
Type -> DataType
Type -> Constr
(forall b. Data b => b -> b) -> Type -> Type
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Type -> c Type
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Type
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Type -> u
forall u. (forall d. Data d => d -> u) -> Type -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Type -> m Type
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Type -> m Type
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Type
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Type -> c Type
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Type)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Type)
$cCoercionTy :: Constr
$cCastTy :: Constr
$cLitTy :: Constr
$cFunTy :: Constr
$cForAllTy :: Constr
$cTyConApp :: Constr
$cAppTy :: Constr
$cTyVarTy :: Constr
$tType :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Type -> m Type
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Type -> m Type
gmapMp :: (forall d. Data d => d -> m d) -> Type -> m Type
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Type -> m Type
gmapM :: (forall d. Data d => d -> m d) -> Type -> m Type
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Type -> m Type
gmapQi :: Int -> (forall d. Data d => d -> u) -> Type -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Type -> u
gmapQ :: (forall d. Data d => d -> u) -> Type -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Type -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Type -> r
gmapT :: (forall b. Data b => b -> b) -> Type -> Type
$cgmapT :: (forall b. Data b => b -> b) -> Type -> Type
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Type)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Type)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Type)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Type)
dataTypeOf :: Type -> DataType
$cdataTypeOf :: Type -> DataType
toConstr :: Type -> Constr
$ctoConstr :: Type -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Type
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Type
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Type -> c Type
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Type -> c Type
$cp1Data :: Typeable Type
Data.Data


-- NOTE:  Other parts of the code assume that type literals do not contain
-- types or type variables.
data TyLit
  = NumTyLit Integer
  | StrTyLit FastString
  deriving (TyLit -> TyLit -> Bool
(TyLit -> TyLit -> Bool) -> (TyLit -> TyLit -> Bool) -> Eq TyLit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TyLit -> TyLit -> Bool
$c/= :: TyLit -> TyLit -> Bool
== :: TyLit -> TyLit -> Bool
$c== :: TyLit -> TyLit -> Bool
Eq, Eq TyLit
Eq TyLit
-> (TyLit -> TyLit -> Ordering)
-> (TyLit -> TyLit -> Bool)
-> (TyLit -> TyLit -> Bool)
-> (TyLit -> TyLit -> Bool)
-> (TyLit -> TyLit -> Bool)
-> (TyLit -> TyLit -> TyLit)
-> (TyLit -> TyLit -> TyLit)
-> Ord TyLit
TyLit -> TyLit -> Bool
TyLit -> TyLit -> Ordering
TyLit -> TyLit -> TyLit
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
min :: TyLit -> TyLit -> TyLit
$cmin :: TyLit -> TyLit -> TyLit
max :: TyLit -> TyLit -> TyLit
$cmax :: TyLit -> TyLit -> TyLit
>= :: TyLit -> TyLit -> Bool
$c>= :: TyLit -> TyLit -> Bool
> :: TyLit -> TyLit -> Bool
$c> :: TyLit -> TyLit -> Bool
<= :: TyLit -> TyLit -> Bool
$c<= :: TyLit -> TyLit -> Bool
< :: TyLit -> TyLit -> Bool
$c< :: TyLit -> TyLit -> Bool
compare :: TyLit -> TyLit -> Ordering
$ccompare :: TyLit -> TyLit -> Ordering
$cp1Ord :: Eq TyLit
Ord, Typeable TyLit
DataType
Constr
Typeable TyLit
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TyLit -> c TyLit)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TyLit)
-> (TyLit -> Constr)
-> (TyLit -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TyLit))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyLit))
-> ((forall b. Data b => b -> b) -> TyLit -> TyLit)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r)
-> (forall u. (forall d. Data d => d -> u) -> TyLit -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> TyLit -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TyLit -> m TyLit)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TyLit -> m TyLit)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TyLit -> m TyLit)
-> Data TyLit
TyLit -> DataType
TyLit -> Constr
(forall b. Data b => b -> b) -> TyLit -> TyLit
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyLit -> c TyLit
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyLit
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> TyLit -> u
forall u. (forall d. Data d => d -> u) -> TyLit -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TyLit -> m TyLit
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TyLit -> m TyLit
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyLit
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyLit -> c TyLit
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TyLit)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyLit)
$cStrTyLit :: Constr
$cNumTyLit :: Constr
$tTyLit :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> TyLit -> m TyLit
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TyLit -> m TyLit
gmapMp :: (forall d. Data d => d -> m d) -> TyLit -> m TyLit
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TyLit -> m TyLit
gmapM :: (forall d. Data d => d -> m d) -> TyLit -> m TyLit
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TyLit -> m TyLit
gmapQi :: Int -> (forall d. Data d => d -> u) -> TyLit -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TyLit -> u
gmapQ :: (forall d. Data d => d -> u) -> TyLit -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> TyLit -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TyLit -> r
gmapT :: (forall b. Data b => b -> b) -> TyLit -> TyLit
$cgmapT :: (forall b. Data b => b -> b) -> TyLit -> TyLit
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyLit)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyLit)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c TyLit)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TyLit)
dataTypeOf :: TyLit -> DataType
$cdataTypeOf :: TyLit -> DataType
toConstr :: TyLit -> Constr
$ctoConstr :: TyLit -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyLit
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyLit
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyLit -> c TyLit
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyLit -> c TyLit
$cp1Data :: Typeable TyLit
Data.Data)

{- Note [Arguments to type constructors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because of kind polymorphism, in addition to type application we now
have kind instantiation. We reuse the same notations to do so.

For example:

  Just (* -> *) Maybe
  Right * Nat Zero

are represented by:

  TyConApp (PromotedDataCon Just) [* -> *, Maybe]
  TyConApp (PromotedDataCon Right) [*, Nat, (PromotedDataCon Zero)]

Important note: Nat is used as a *kind* and not as a type. This can be
confusing, since type-level Nat and kind-level Nat are identical. We
use the kind of (PromotedDataCon Right) to know if its arguments are
kinds or types.

This kind instantiation only happens in TyConApp currently.

Note [Non-trivial definitional equality]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is Int |> <*> the same as Int? YES! In order to reduce headaches,
we decide that any reflexive casts in types are just ignored.
(Indeed they must be. See Note [Respecting definitional equality].)
More generally, the `eqType` function, which defines Core's type equality
relation, ignores casts and coercion arguments, as long as the
two types have the same kind. This allows us to be a little sloppier
in keeping track of coercions, which is a good thing. It also means
that eqType does not depend on eqCoercion, which is also a good thing.

Why is this sensible? That is, why is something different than α-equivalence
appropriate for the implementation of eqType?

Anything smaller than ~ and homogeneous is an appropriate definition for
equality. The type safety of FC depends only on ~. Let's say η : τ ~ σ. Any
expression of type τ can be transmuted to one of type σ at any point by
casting. The same is true of expressions of type σ. So in some sense, τ and σ
are interchangeable.

But let's be more precise. If we examine the typing rules of FC (say, those in
https://cs.brynmawr.edu/~rae/papers/2015/equalities/equalities.pdf)
there are several places where the same metavariable is used in two different
premises to a rule. (For example, see Ty_App.) There is an implicit equality
check here. What definition of equality should we use? By convention, we use
α-equivalence. Take any rule with one (or more) of these implicit equality
checks. Then there is an admissible rule that uses ~ instead of the implicit
check, adding in casts as appropriate.

The only problem here is that ~ is heterogeneous. To make the kinds work out
in the admissible rule that uses ~, it is necessary to homogenize the
coercions. That is, if we have η : (τ : κ1) ~ (σ : κ2), then we don't use η;
we use η |> kind η, which is homogeneous.

The effect of this all is that eqType, the implementation of the implicit
equality check, can use any homogeneous relation that is smaller than ~, as
those rules must also be admissible.

A more drawn out argument around all of this is presented in Section 7.2 of
Richard E's thesis (http://cs.brynmawr.edu/~rae/papers/2016/thesis/eisenberg-thesis.pdf).

What would go wrong if we insisted on the casts matching? See the beginning of
Section 8 in the unpublished paper above. Theoretically, nothing at all goes
wrong. But in practical terms, getting the coercions right proved to be
nightmarish. And types would explode: during kind-checking, we often produce
reflexive kind coercions. When we try to cast by these, mkCastTy just discards
them. But if we used an eqType that distinguished between Int and Int |> <*>,
then we couldn't discard -- the output of kind-checking would be enormous,
and we would need enormous casts with lots of CoherenceCo's to straighten
them out.

Would anything go wrong if eqType respected type families? No, not at all. But
that makes eqType rather hard to implement.

Thus, the guideline for eqType is that it should be the largest
easy-to-implement relation that is still smaller than ~ and homogeneous. The
precise choice of relation is somewhat incidental, as long as the smart
constructors and destructors in Type respect whatever relation is chosen.

Another helpful principle with eqType is this:

 (EQ) If (t1 `eqType` t2) then I can replace t1 by t2 anywhere.

This principle also tells us that eqType must relate only types with the
same kinds.

Note [Respecting definitional equality]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note [Non-trivial definitional equality] introduces the property (EQ).
How is this upheld?

Any function that pattern matches on all the constructors will have to
consider the possibility of CastTy. Presumably, those functions will handle
CastTy appropriately and we'll be OK.

More dangerous are the splitXXX functions. Let's focus on splitTyConApp.
We don't want it to fail on (T a b c |> co). Happily, if we have
  (T a b c |> co) `eqType` (T d e f)
then co must be reflexive. Why? eqType checks that the kinds are equal, as
well as checking that (a `eqType` d), (b `eqType` e), and (c `eqType` f).
By the kind check, we know that (T a b c |> co) and (T d e f) have the same
kind. So the only way that co could be non-reflexive is for (T a b c) to have
a different kind than (T d e f). But because T's kind is closed (all tycon kinds
are closed), the only way for this to happen is that one of the arguments has
to differ, leading to a contradiction. Thus, co is reflexive.

Accordingly, by eliminating reflexive casts, splitTyConApp need not worry
about outermost casts to uphold (EQ). Eliminating reflexive casts is done
in mkCastTy.

Unforunately, that's not the end of the story. Consider comparing
  (T a b c)      =?       (T a b |> (co -> <Type>)) (c |> co)
These two types have the same kind (Type), but the left type is a TyConApp
while the right type is not. To handle this case, we say that the right-hand
type is ill-formed, requiring an AppTy never to have a casted TyConApp
on its left. It is easy enough to pull around the coercions to maintain
this invariant, as done in Type.mkAppTy. In the example above, trying to
form the right-hand type will instead yield (T a b (c |> co |> sym co) |> <Type>).
Both the casts there are reflexive and will be dropped. Huzzah.

This idea of pulling coercions to the right works for splitAppTy as well.

However, there is one hiccup: it's possible that a coercion doesn't relate two
Pi-types. For example, if we have @type family Fun a b where Fun a b = a -> b@,
then we might have (T :: Fun Type Type) and (T |> axFun) Int. That axFun can't
be pulled to the right. But we don't need to pull it: (T |> axFun) Int is not
`eqType` to any proper TyConApp -- thus, leaving it where it is doesn't violate
our (EQ) property.

Lastly, in order to detect reflexive casts reliably, we must make sure not
to have nested casts: we update (t |> co1 |> co2) to (t |> (co1 `TransCo` co2)).

In sum, in order to uphold (EQ), we need the following three invariants:

  (EQ1) No decomposable CastTy to the left of an AppTy, where a decomposable
        cast is one that relates either a FunTy to a FunTy or a
        ForAllTy to a ForAllTy.
  (EQ2) No reflexive casts in CastTy.
  (EQ3) No nested CastTys.
  (EQ4) No CastTy over (ForAllTy (Bndr tyvar vis) body).
        See Note [Weird typing rule for ForAllTy] in Type.

These invariants are all documented above, in the declaration for Type.

Note [Unused coercion variable in ForAllTy]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose we have
  \(co:t1 ~ t2). e

What type should we give to this expression?
  (1) forall (co:t1 ~ t2) -> t
  (2) (t1 ~ t2) -> t

If co is used in t, (1) should be the right choice.
if co is not used in t, we would like to have (1) and (2) equivalent.

However, we want to keep eqType simple and don't want eqType (1) (2) to return
True in any case.

We decide to always construct (2) if co is not used in t.

Thus in mkTyCoForAllTy, we check whether the variable is a coercion
variable and whether it is used in the body. If so, it returns a FunTy
instead of a ForAllTy.

There are cases we want to skip the check. For example, the check is unnecessary
when it is known from the context that the input variable is a type variable.
In those cases, we use mkForAllTy.
-}

-- | A type labeled 'KnotTied' might have knot-tied tycons in it. See
-- Note [Type checking recursive type and class declarations] in
-- TcTyClsDecls
type KnotTied ty = ty

{- **********************************************************************
*                                                                       *
                  TyCoBinder and ArgFlag
*                                                                       *
********************************************************************** -}

-- | A 'TyCoBinder' represents an argument to a function. TyCoBinders can be
-- dependent ('Named') or nondependent ('Anon'). They may also be visible or
-- not. See Note [TyCoBinders]
data TyCoBinder
  = Named TyCoVarBinder -- A type-lambda binder
  | Anon Type           -- A term-lambda binder. Type here can be CoercionTy.
                        -- Visibility is determined by the type (Constraint vs. *)
  deriving Typeable TyCoBinder
DataType
Constr
Typeable TyCoBinder
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TyCoBinder -> c TyCoBinder)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TyCoBinder)
-> (TyCoBinder -> Constr)
-> (TyCoBinder -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TyCoBinder))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c TyCoBinder))
-> ((forall b. Data b => b -> b) -> TyCoBinder -> TyCoBinder)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r)
-> (forall u. (forall d. Data d => d -> u) -> TyCoBinder -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> TyCoBinder -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder)
-> Data TyCoBinder
TyCoBinder -> DataType
TyCoBinder -> Constr
(forall b. Data b => b -> b) -> TyCoBinder -> TyCoBinder
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyCoBinder -> c TyCoBinder
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyCoBinder
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> TyCoBinder -> u
forall u. (forall d. Data d => d -> u) -> TyCoBinder -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyCoBinder
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyCoBinder -> c TyCoBinder
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TyCoBinder)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyCoBinder)
$cAnon :: Constr
$cNamed :: Constr
$tTyCoBinder :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
gmapMp :: (forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
gmapM :: (forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TyCoBinder -> m TyCoBinder
gmapQi :: Int -> (forall d. Data d => d -> u) -> TyCoBinder -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TyCoBinder -> u
gmapQ :: (forall d. Data d => d -> u) -> TyCoBinder -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> TyCoBinder -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TyCoBinder -> r
gmapT :: (forall b. Data b => b -> b) -> TyCoBinder -> TyCoBinder
$cgmapT :: (forall b. Data b => b -> b) -> TyCoBinder -> TyCoBinder
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyCoBinder)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TyCoBinder)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c TyCoBinder)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TyCoBinder)
dataTypeOf :: TyCoBinder -> DataType
$cdataTypeOf :: TyCoBinder -> DataType
toConstr :: TyCoBinder -> Constr
$ctoConstr :: TyCoBinder -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyCoBinder
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TyCoBinder
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyCoBinder -> c TyCoBinder
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TyCoBinder -> c TyCoBinder
$cp1Data :: Typeable TyCoBinder
Data.Data

-- | 'TyBinder' is like 'TyCoBinder', but there can only be 'TyVarBinder'
-- in the 'Named' field.
type TyBinder = TyCoBinder

-- | Remove the binder's variable from the set, if the binder has
-- a variable.
delBinderVar :: VarSet -> TyCoVarBinder -> VarSet
delBinderVar :: VarSet -> TyCoVarBinder -> VarSet
delBinderVar VarSet
vars (Bndr Id
tv ArgFlag
_) = VarSet
vars VarSet -> Id -> VarSet
`delVarSet` Id
tv

-- | Does this binder bind an invisible argument?
isInvisibleBinder :: TyCoBinder -> Bool
isInvisibleBinder :: TyCoBinder -> Bool
isInvisibleBinder (Named (Bndr Id
_ ArgFlag
vis)) = ArgFlag -> Bool
isInvisibleArgFlag ArgFlag
vis
isInvisibleBinder (Anon Type
ty)            = Type -> Bool
isPredTy Type
ty

-- | Does this binder bind a visible argument?
isVisibleBinder :: TyCoBinder -> Bool
isVisibleBinder :: TyCoBinder -> Bool
isVisibleBinder = Bool -> Bool
not (Bool -> Bool) -> (TyCoBinder -> Bool) -> TyCoBinder -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCoBinder -> Bool
isInvisibleBinder

isNamedBinder :: TyCoBinder -> Bool
isNamedBinder :: TyCoBinder -> Bool
isNamedBinder (Named {}) = Bool
True
isNamedBinder (Anon {})  = Bool
False

-- | If its a named binder, is the binder a tyvar?
-- Returns True for nondependent binder.
isTyBinder :: TyCoBinder -> Bool
isTyBinder :: TyCoBinder -> Bool
isTyBinder (Named TyCoVarBinder
bnd) = TyCoVarBinder -> Bool
isTyVarBinder TyCoVarBinder
bnd
isTyBinder TyCoBinder
_ = Bool
True

tyCoBinderArgFlag :: TyCoBinder -> ArgFlag
tyCoBinderArgFlag :: TyCoBinder -> ArgFlag
tyCoBinderArgFlag (Named (Bndr Id
_ ArgFlag
flag)) = ArgFlag
flag
tyCoBinderArgFlag (Anon Type
ty)
 | Type -> Bool
isPredTy Type
ty = ArgFlag
Inferred
 | Bool
otherwise = ArgFlag
Required

{- Note [TyCoBinders]
~~~~~~~~~~~~~~~~~~~
A ForAllTy contains a TyCoVarBinder.  But a type can be decomposed
to a telescope consisting of a [TyCoBinder]

A TyCoBinder represents the type of binders -- that is, the type of an
argument to a Pi-type. GHC Core currently supports two different
Pi-types:

 * A non-dependent function type,
   written with ->, e.g. ty1 -> ty2
   represented as FunTy ty1 ty2. These are
   lifted to Coercions with the corresponding FunCo.

 * A dependent compile-time-only polytype,
   written with forall, e.g.  forall (a:*). ty
   represented as ForAllTy (Bndr a v) ty

Both Pi-types classify terms/types that take an argument. In other
words, if `x` is either a function or a polytype, `x arg` makes sense
(for an appropriate `arg`).


Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* A ForAllTy (used for both types and kinds) contains a TyCoVarBinder.
  Each TyCoVarBinder
      Bndr a tvis
  is equipped with tvis::ArgFlag, which says whether or not arguments
  for this binder should be visible (explicit) in source Haskell.

* A TyCon contains a list of TyConBinders.  Each TyConBinder
      Bndr a cvis
  is equipped with cvis::TyConBndrVis, which says whether or not type
  and kind arguments for this TyCon should be visible (explicit) in
  source Haskell.

This table summarises the visibility rules:
---------------------------------------------------------------------------------------
|                                                      Occurrences look like this
|                             GHC displays type as     in Haskell source code
|--------------------------------------------------------------------------------------
| Bndr a tvis :: TyCoVarBinder, in the binder of ForAllTy for a term
|  tvis :: ArgFlag
|  tvis = Inferred:            f :: forall {a}. type    Arg not allowed:  f
                               f :: forall {co}. type   Arg not allowed:  f
|  tvis = Specified:           f :: forall a. type      Arg optional:     f  or  f @Int
|  tvis = Required:            T :: forall k -> type    Arg required:     T *
|    This last form is illegal in terms: See Note [No Required TyCoBinder in terms]
|
| Bndr k cvis :: TyConBinder, in the TyConBinders of a TyCon
|  cvis :: TyConBndrVis
|  cvis = AnonTCB:             T :: kind -> kind        Required:            T *
|  cvis = NamedTCB Inferred:   T :: forall {k}. kind    Arg not allowed:     T
|                              T :: forall {co}. kind   Arg not allowed:     T
|  cvis = NamedTCB Specified:  T :: forall k. kind      Arg not allowed[1]:  T
|  cvis = NamedTCB Required:   T :: forall k -> kind    Required:            T *
---------------------------------------------------------------------------------------

[1] In types, in the Specified case, it would make sense to allow
    optional kind applications, thus (T @*), but we have not
    yet implemented that

---- In term declarations ----

* Inferred.  Function defn, with no signature:  f1 x = x
  We infer f1 :: forall {a}. a -> a, with 'a' Inferred
  It's Inferred because it doesn't appear in any
  user-written signature for f1

* Specified.  Function defn, with signature (implicit forall):
     f2 :: a -> a; f2 x = x
  So f2 gets the type f2 :: forall a. a -> a, with 'a' Specified
  even though 'a' is not bound in the source code by an explicit forall

* Specified.  Function defn, with signature (explicit forall):
     f3 :: forall a. a -> a; f3 x = x
  So f3 gets the type f3 :: forall a. a -> a, with 'a' Specified

* Inferred/Specified.  Function signature with inferred kind polymorphism.
     f4 :: a b -> Int
  So 'f4' gets the type f4 :: forall {k} (a:k->*) (b:k). a b -> Int
  Here 'k' is Inferred (it's not mentioned in the type),
  but 'a' and 'b' are Specified.

* Specified.  Function signature with explicit kind polymorphism
     f5 :: a (b :: k) -> Int
  This time 'k' is Specified, because it is mentioned explicitly,
  so we get f5 :: forall (k:*) (a:k->*) (b:k). a b -> Int

* Similarly pattern synonyms:
  Inferred - from inferred types (e.g. no pattern type signature)
           - or from inferred kind polymorphism

---- In type declarations ----

* Inferred (k)
     data T1 a b = MkT1 (a b)
  Here T1's kind is  T1 :: forall {k:*}. (k->*) -> k -> *
  The kind variable 'k' is Inferred, since it is not mentioned

  Note that 'a' and 'b' correspond to /Anon/ TyCoBinders in T1's kind,
  and Anon binders don't have a visibility flag. (Or you could think
  of Anon having an implicit Required flag.)

* Specified (k)
     data T2 (a::k->*) b = MkT (a b)
  Here T's kind is  T :: forall (k:*). (k->*) -> k -> *
  The kind variable 'k' is Specified, since it is mentioned in
  the signature.

* Required (k)
     data T k (a::k->*) b = MkT (a b)
  Here T's kind is  T :: forall k:* -> (k->*) -> k -> *
  The kind is Required, since it bound in a positional way in T's declaration
  Every use of T must be explicitly applied to a kind

* Inferred (k1), Specified (k)
     data T a b (c :: k) = MkT (a b) (Proxy c)
  Here T's kind is  T :: forall {k1:*} (k:*). (k1->*) -> k1 -> k -> *
  So 'k' is Specified, because it appears explicitly,
  but 'k1' is Inferred, because it does not

Generally, in the list of TyConBinders for a TyCon,

* Inferred arguments always come first
* Specified, Anon and Required can be mixed

e.g.
  data Foo (a :: Type) :: forall b. (a -> b -> Type) -> Type where ...

Here Foo's TyConBinders are
   [Required 'a', Specified 'b', Anon]
and its kind prints as
   Foo :: forall a -> forall b. (a -> b -> Type) -> Type

See also Note [Required, Specified, and Inferred for types] in TcTyClsDecls

---- Printing -----

 We print forall types with enough syntax to tell you their visibility
 flag.  But this is not source Haskell, and these types may not all
 be parsable.

 Specified: a list of Specified binders is written between `forall` and `.`:
               const :: forall a b. a -> b -> a

 Inferred:  with -fprint-explicit-foralls, Inferred binders are written
            in braces:
               f :: forall {k} (a:k). S k a -> Int
            Otherwise, they are printed like Specified binders.

 Required: binders are put between `forall` and `->`:
              T :: forall k -> *

---- Other points -----

* In classic Haskell, all named binders (that is, the type variables in
  a polymorphic function type f :: forall a. a -> a) have been Inferred.

* Inferred variables correspond to "generalized" variables from the
  Visible Type Applications paper (ESOP'16).

Note [No Required TyCoBinder in terms]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We don't allow Required foralls for term variables, including pattern
synonyms and data constructors.  Why?  Because then an application
would need a /compulsory/ type argument (possibly without an "@"?),
thus (f Int); and we don't have concrete syntax for that.

We could change this decision, but Required, Named TyCoBinders are rare
anyway.  (Most are Anons.)

However the type of a term can (just about) have a required quantifier;
see Note [Required quantifiers in the type of a term] in TcExpr.
-}


{- **********************************************************************
*                                                                       *
                        PredType
*                                                                       *
********************************************************************** -}


-- | A type of the form @p@ of kind @Constraint@ represents a value whose type is
-- the Haskell predicate @p@, where a predicate is what occurs before
-- the @=>@ in a Haskell type.
--
-- We use 'PredType' as documentation to mark those types that we guarantee to have
-- this kind.
--
-- It can be expanded into its representation, but:
--
-- * The type checker must treat it as opaque
--
-- * The rest of the compiler treats it as transparent
--
-- Consider these examples:
--
-- > f :: (Eq a) => a -> Int
-- > g :: (?x :: Int -> Int) => a -> Int
-- > h :: (r\l) => {r} => {l::Int | r}
--
-- Here the @Eq a@ and @?x :: Int -> Int@ and @r\l@ are all called \"predicates\"
type PredType = Type

-- | A collection of 'PredType's
type ThetaType = [PredType]

{-
(We don't support TREX records yet, but the setup is designed
to expand to allow them.)

A Haskell qualified type, such as that for f,g,h above, is
represented using
        * a FunTy for the double arrow
        * with a type of kind Constraint as the function argument

The predicate really does turn into a real extra argument to the
function.  If the argument has type (p :: Constraint) then the predicate p is
represented by evidence of type p.


%************************************************************************
%*                                                                      *
            Simple constructors
%*                                                                      *
%************************************************************************

These functions are here so that they can be used by TysPrim,
which in turn is imported by Type
-}

mkTyVarTy  :: TyVar   -> Type
mkTyVarTy :: Id -> Type
mkTyVarTy Id
v = ASSERT2( isTyVar v, ppr v <+> dcolon <+> ppr (tyVarKind v) )
              Id -> Type
TyVarTy Id
v

mkTyVarTys :: [TyVar] -> [Type]
mkTyVarTys :: [Id] -> [Type]
mkTyVarTys = (Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
mkTyVarTy -- a common use of mkTyVarTy

mkTyCoVarTy :: TyCoVar -> Type
mkTyCoVarTy :: Id -> Type
mkTyCoVarTy Id
v
  | Id -> Bool
isTyVar Id
v
  = Id -> Type
TyVarTy Id
v
  | Bool
otherwise
  = Coercion -> Type
CoercionTy (Id -> Coercion
CoVarCo Id
v)

mkTyCoVarTys :: [TyCoVar] -> [Type]
mkTyCoVarTys :: [Id] -> [Type]
mkTyCoVarTys = (Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
mkTyCoVarTy

infixr 3 `mkFunTy`      -- Associates to the right
-- | Make an arrow type
mkFunTy :: Type -> Type -> Type
mkFunTy :: Type -> Type -> Type
mkFunTy Type
arg Type
res = Type -> Type -> Type
FunTy Type
arg Type
res

-- | Make nested arrow types
mkFunTys :: [Type] -> Type -> Type
mkFunTys :: [Type] -> Type -> Type
mkFunTys [Type]
tys Type
ty = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
mkFunTy Type
ty [Type]
tys

-- | If tv is a coercion variable and it is not used in the body, returns
-- a FunTy, otherwise makes a forall type.
-- See Note [Unused coercion variable in ForAllTy]
mkTyCoForAllTy :: TyCoVar -> ArgFlag -> Type -> Type
mkTyCoForAllTy :: Id -> ArgFlag -> Type -> Type
mkTyCoForAllTy Id
tv ArgFlag
vis Type
ty
  | Id -> Bool
isCoVar Id
tv
  , Bool -> Bool
not (Id
tv Id -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
ty)
  = ASSERT( vis == Inferred )
    Type -> Type -> Type
mkFunTy (Id -> Type
varType Id
tv) Type
ty
  | Bool
otherwise
  = TyCoVarBinder -> Type -> Type
ForAllTy (Id -> ArgFlag -> TyCoVarBinder
forall var argf. var -> argf -> VarBndr var argf
Bndr Id
tv ArgFlag
vis) Type
ty

-- | Like 'mkTyCoForAllTy', but does not check the occurrence of the binder
-- See Note [Unused coercion variable in ForAllTy]
mkForAllTy :: TyCoVar -> ArgFlag -> Type -> Type
mkForAllTy :: Id -> ArgFlag -> Type -> Type
mkForAllTy Id
tv ArgFlag
vis Type
ty = TyCoVarBinder -> Type -> Type
ForAllTy (Id -> ArgFlag -> TyCoVarBinder
forall var argf. var -> argf -> VarBndr var argf
Bndr Id
tv ArgFlag
vis) Type
ty

-- | Wraps foralls over the type using the provided 'TyCoVar's from left to right
mkForAllTys :: [TyCoVarBinder] -> Type -> Type
mkForAllTys :: [TyCoVarBinder] -> Type -> Type
mkForAllTys [TyCoVarBinder]
tyvars Type
ty = (TyCoVarBinder -> Type -> Type) -> Type -> [TyCoVarBinder] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr TyCoVarBinder -> Type -> Type
ForAllTy Type
ty [TyCoVarBinder]
tyvars

mkTyCoPiTy :: TyCoBinder -> Type -> Type
mkTyCoPiTy :: TyCoBinder -> Type -> Type
mkTyCoPiTy (Anon Type
ty1) Type
ty2           = Type -> Type -> Type
FunTy Type
ty1 Type
ty2
mkTyCoPiTy (Named (Bndr Id
tv ArgFlag
vis)) Type
ty = Id -> ArgFlag -> Type -> Type
mkTyCoForAllTy Id
tv ArgFlag
vis Type
ty

-- | Like 'mkTyCoPiTy', but does not check the occurrence of the binder
mkPiTy:: TyCoBinder -> Type -> Type
mkPiTy :: TyCoBinder -> Type -> Type
mkPiTy (Anon Type
ty1) Type
ty2           = Type -> Type -> Type
FunTy Type
ty1 Type
ty2
mkPiTy (Named (Bndr Id
tv ArgFlag
vis)) Type
ty = Id -> ArgFlag -> Type -> Type
mkForAllTy Id
tv ArgFlag
vis Type
ty

mkTyCoPiTys :: [TyCoBinder] -> Type -> Type
mkTyCoPiTys :: [TyCoBinder] -> Type -> Type
mkTyCoPiTys [TyCoBinder]
tbs Type
ty = (TyCoBinder -> Type -> Type) -> Type -> [TyCoBinder] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr TyCoBinder -> Type -> Type
mkTyCoPiTy Type
ty [TyCoBinder]
tbs

-- | Like 'mkTyCoPiTys', but does not check the occurrence of the binder
mkPiTys :: [TyCoBinder] -> Type -> Type
mkPiTys :: [TyCoBinder] -> Type -> Type
mkPiTys [TyCoBinder]
tbs Type
ty = (TyCoBinder -> Type -> Type) -> Type -> [TyCoBinder] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr TyCoBinder -> Type -> Type
mkPiTy Type
ty [TyCoBinder]
tbs

-- | Create the plain type constructor type which has been applied to no type arguments at all.
mkTyConTy :: TyCon -> Type
mkTyConTy :: TyCon -> Type
mkTyConTy TyCon
tycon = TyCon -> [Type] -> Type
TyConApp TyCon
tycon []

{-
Some basic functions, put here to break loops eg with the pretty printer
-}

-- | Extract the RuntimeRep classifier of a type from its kind. For example,
-- @kindRep * = LiftedRep@; Panics if this is not possible.
-- Treats * and Constraint as the same
kindRep :: HasDebugCallStack => Kind -> Type
kindRep :: Type -> Type
kindRep Type
k = case HasDebugCallStack => Type -> Maybe Type
Type -> Maybe Type
kindRep_maybe Type
k of
              Just Type
r  -> Type
r
              Maybe Type
Nothing -> String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"kindRep" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
k)

-- | Given a kind (TYPE rr), extract its RuntimeRep classifier rr.
-- For example, @kindRep_maybe * = Just LiftedRep@
-- Returns 'Nothing' if the kind is not of form (TYPE rr)
-- Treats * and Constraint as the same
kindRep_maybe :: HasDebugCallStack => Kind -> Maybe Type
kindRep_maybe :: Type -> Maybe Type
kindRep_maybe Type
kind
  | Just Type
kind' <- Type -> Maybe Type
coreView Type
kind = HasDebugCallStack => Type -> Maybe Type
Type -> Maybe Type
kindRep_maybe Type
kind'
  | TyConApp TyCon
tc [Type
arg] <- Type
kind
  , TyCon
tc TyCon -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
tYPETyConKey    = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
arg
  | Bool
otherwise                   = Maybe Type
forall a. Maybe a
Nothing

-- | This version considers Constraint to be the same as *. Returns True
-- if the argument is equivalent to Type/Constraint and False otherwise.
-- See Note [Kind Constraint and kind Type]
isLiftedTypeKind :: Kind -> Bool
isLiftedTypeKind :: Type -> Bool
isLiftedTypeKind Type
kind
  = case HasDebugCallStack => Type -> Maybe Type
Type -> Maybe Type
kindRep_maybe Type
kind of
      Just Type
rep -> Type -> Bool
isLiftedRuntimeRep Type
rep
      Maybe Type
Nothing  -> Bool
False

-- | Returns True if the kind classifies unlifted types and False otherwise.
-- Note that this returns False for levity-polymorphic kinds, which may
-- be specialized to a kind that classifies unlifted types.
isUnliftedTypeKind :: Kind -> Bool
isUnliftedTypeKind :: Type -> Bool
isUnliftedTypeKind Type
kind
  = case HasDebugCallStack => Type -> Maybe Type
Type -> Maybe Type
kindRep_maybe Type
kind of
      Just Type
rep -> Type -> Bool
isUnliftedRuntimeRep Type
rep
      Maybe Type
Nothing  -> Bool
False

isLiftedRuntimeRep, isUnliftedRuntimeRep :: Type -> Bool
-- isLiftedRuntimeRep is true of LiftedRep :: RuntimeRep
-- Similarly isUnliftedRuntimeRep
isLiftedRuntimeRep :: Type -> Bool
isLiftedRuntimeRep Type
rep
  | Just Type
rep' <- Type -> Maybe Type
coreView Type
rep          = Type -> Bool
isLiftedRuntimeRep Type
rep'
  | TyConApp TyCon
rr_tc [Type]
args <- Type
rep
  , TyCon
rr_tc TyCon -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
liftedRepDataConKey = ASSERT( null args ) True
  | Bool
otherwise                          = Bool
False

isUnliftedRuntimeRep :: Type -> Bool
isUnliftedRuntimeRep Type
rep
  | Just Type
rep' <- Type -> Maybe Type
coreView Type
rep          = Type -> Bool
isUnliftedRuntimeRep Type
rep'
  | TyConApp TyCon
rr_tc [Type]
args <- Type
rep
  , TyCon -> Bool
isUnliftedRuntimeRepTyCon TyCon
rr_tc    = ASSERT( null args ) True
  | Bool
otherwise                          = Bool
False

isUnliftedRuntimeRepTyCon :: TyCon -> Bool
isUnliftedRuntimeRepTyCon :: TyCon -> Bool
isUnliftedRuntimeRepTyCon TyCon
rr_tc
  = Unique -> [Unique] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem (TyCon -> Unique
forall a. Uniquable a => a -> Unique
getUnique TyCon
rr_tc) [Unique]
unliftedRepDataConKeys

-- | Is this the type 'RuntimeRep'?
isRuntimeRepTy :: Type -> Bool
isRuntimeRepTy :: Type -> Bool
isRuntimeRepTy Type
ty | Just Type
ty' <- Type -> Maybe Type
coreView Type
ty = Type -> Bool
isRuntimeRepTy Type
ty'
isRuntimeRepTy (TyConApp TyCon
tc []) = TyCon
tc TyCon -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
runtimeRepTyConKey
isRuntimeRepTy Type
_ = Bool
False

-- | Is a tyvar of type 'RuntimeRep'?
isRuntimeRepVar :: TyVar -> Bool
isRuntimeRepVar :: Id -> Bool
isRuntimeRepVar = Type -> Bool
isRuntimeRepTy (Type -> Bool) -> (Id -> Type) -> Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Type
tyVarKind

{-
%************************************************************************
%*                                                                      *
            Coercions
%*                                                                      *
%************************************************************************
-}

-- | A 'Coercion' is concrete evidence of the equality/convertibility
-- of two types.

-- If you edit this type, you may need to update the GHC formalism
-- See Note [GHC Formalism] in coreSyn/CoreLint.hs
data Coercion
  -- Each constructor has a "role signature", indicating the way roles are
  -- propagated through coercions.
  --    -  P, N, and R stand for coercions of the given role
  --    -  e stands for a coercion of a specific unknown role
  --           (think "role polymorphism")
  --    -  "e" stands for an explicit role parameter indicating role e.
  --    -   _ stands for a parameter that is not a Role or Coercion.

  -- These ones mirror the shape of types
  = -- Refl :: _ -> N
    Refl Type  -- See Note [Refl invariant]
          -- Invariant: applications of (Refl T) to a bunch of identity coercions
          --            always show up as Refl.
          -- For example  (Refl T) (Refl a) (Refl b) shows up as (Refl (T a b)).

          -- Applications of (Refl T) to some coercions, at least one of
          -- which is NOT the identity, show up as TyConAppCo.
          -- (They may not be fully saturated however.)
          -- ConAppCo coercions (like all coercions other than Refl)
          -- are NEVER the identity.

          -- Use (GRefl Representational ty MRefl), not (SubCo (Refl ty))

  -- GRefl :: "e" -> _ -> Maybe N -> e
  -- See Note [Generalized reflexive coercion]
  | GRefl Role Type MCoercionN  -- See Note [Refl invariant]
          -- Use (Refl ty), not (GRefl Nominal ty MRefl)
          -- Use (GRefl Representational _ _), not (SubCo (GRefl Nominal _ _))

  -- These ones simply lift the correspondingly-named
  -- Type constructors into Coercions

  -- TyConAppCo :: "e" -> _ -> ?? -> e
  -- See Note [TyConAppCo roles]
  | TyConAppCo Role TyCon [Coercion]    -- lift TyConApp
               -- The TyCon is never a synonym;
               -- we expand synonyms eagerly
               -- But it can be a type function

  | AppCo Coercion CoercionN             -- lift AppTy
          -- AppCo :: e -> N -> e

  -- See Note [Forall coercions]
  | ForAllCo TyCoVar KindCoercion Coercion
         -- ForAllCo :: _ -> N -> e -> e

  | FunCo Role Coercion Coercion         -- lift FunTy
         -- FunCo :: "e" -> e -> e -> e

  -- These are special
  | CoVarCo CoVar      -- :: _ -> (N or R)
                       -- result role depends on the tycon of the variable's type

    -- AxiomInstCo :: e -> _ -> [N] -> e
  | AxiomInstCo (CoAxiom Branched) BranchIndex [Coercion]
     -- See also [CoAxiom index]
     -- The coercion arguments always *precisely* saturate
     -- arity of (that branch of) the CoAxiom. If there are
     -- any left over, we use AppCo.
     -- See [Coercion axioms applied to coercions]

  | AxiomRuleCo CoAxiomRule [Coercion]
    -- AxiomRuleCo is very like AxiomInstCo, but for a CoAxiomRule
    -- The number coercions should match exactly the expectations
    -- of the CoAxiomRule (i.e., the rule is fully saturated).

  | UnivCo UnivCoProvenance Role Type Type
      -- :: _ -> "e" -> _ -> _ -> e

  | SymCo Coercion             -- :: e -> e
  | TransCo Coercion Coercion  -- :: e -> e -> e

  | NthCo  Role Int Coercion     -- Zero-indexed; decomposes (T t0 ... tn)
    -- :: "e" -> _ -> e0 -> e (inverse of TyConAppCo, see Note [TyConAppCo roles])
    -- Using NthCo on a ForAllCo gives an N coercion always
    -- See Note [NthCo and newtypes]
    --
    -- Invariant:  (NthCo r i co), it is always the case that r = role of (Nth i co)
    -- That is: the role of the entire coercion is redundantly cached here.
    -- See Note [NthCo Cached Roles]

  | LRCo   LeftOrRight CoercionN     -- Decomposes (t_left t_right)
    -- :: _ -> N -> N
  | InstCo Coercion CoercionN
    -- :: e -> N -> e
    -- See Note [InstCo roles]

  -- Extract a kind coercion from a (heterogeneous) type coercion
  -- NB: all kind coercions are Nominal
  | KindCo Coercion
     -- :: e -> N

  | SubCo CoercionN                  -- Turns a ~N into a ~R
    -- :: N -> R

  | HoleCo CoercionHole              -- ^ See Note [Coercion holes]
                                     -- Only present during typechecking
  deriving Typeable Coercion
DataType
Constr
Typeable Coercion
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Coercion -> c Coercion)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Coercion)
-> (Coercion -> Constr)
-> (Coercion -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Coercion))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Coercion))
-> ((forall b. Data b => b -> b) -> Coercion -> Coercion)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Coercion -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Coercion -> r)
-> (forall u. (forall d. Data d => d -> u) -> Coercion -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Coercion -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Coercion -> m Coercion)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Coercion -> m Coercion)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Coercion -> m Coercion)
-> Data Coercion
Coercion -> DataType
Coercion -> Constr
(forall b. Data b => b -> b) -> Coercion -> Coercion
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Coercion -> c Coercion
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Coercion
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Coercion -> u
forall u. (forall d. Data d => d -> u) -> Coercion -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Coercion -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Coercion -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Coercion -> m Coercion
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Coercion -> m Coercion
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Coercion
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Coercion -> c Coercion
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Coercion)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Coercion)
$cHoleCo :: Constr
$cSubCo :: Constr
$cKindCo :: Constr
$cInstCo :: Constr
$cLRCo :: Constr
$cNthCo :: Constr
$cTransCo :: Constr
$cSymCo :: Constr
$cUnivCo :: Constr
$cAxiomRuleCo :: Constr
$cAxiomInstCo :: Constr
$cCoVarCo :: Constr
$cFunCo :: Constr
$cForAllCo :: Constr
$cAppCo :: Constr
$cTyConAppCo :: Constr
$cGRefl :: Constr
$cRefl :: Constr
$tCoercion :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Coercion -> m Coercion
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Coercion -> m Coercion
gmapMp :: (forall d. Data d => d -> m d) -> Coercion -> m Coercion
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Coercion -> m Coercion
gmapM :: (forall d. Data d => d -> m d) -> Coercion -> m Coercion
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Coercion -> m Coercion
gmapQi :: Int -> (forall d. Data d => d -> u) -> Coercion -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Coercion -> u
gmapQ :: (forall d. Data d => d -> u) -> Coercion -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Coercion -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Coercion -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Coercion -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Coercion -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Coercion -> r
gmapT :: (forall b. Data b => b -> b) -> Coercion -> Coercion
$cgmapT :: (forall b. Data b => b -> b) -> Coercion -> Coercion
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Coercion)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Coercion)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Coercion)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Coercion)
dataTypeOf :: Coercion -> DataType
$cdataTypeOf :: Coercion -> DataType
toConstr :: Coercion -> Constr
$ctoConstr :: Coercion -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Coercion
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Coercion
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Coercion -> c Coercion
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Coercion -> c Coercion
$cp1Data :: Typeable Coercion
Data.Data

type CoercionN = Coercion       -- always nominal
type CoercionR = Coercion       -- always representational
type CoercionP = Coercion       -- always phantom
type KindCoercion = CoercionN   -- always nominal

-- | A semantically more meaningful type to represent what may or may not be a
-- useful 'Coercion'.
data MCoercion
  = MRefl
    -- A trivial Reflexivity coercion
  | MCo Coercion
    -- Other coercions
  deriving Typeable MCoercion
DataType
Constr
Typeable MCoercion
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> MCoercion -> c MCoercion)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c MCoercion)
-> (MCoercion -> Constr)
-> (MCoercion -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c MCoercion))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MCoercion))
-> ((forall b. Data b => b -> b) -> MCoercion -> MCoercion)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> MCoercion -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> MCoercion -> r)
-> (forall u. (forall d. Data d => d -> u) -> MCoercion -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> MCoercion -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> MCoercion -> m MCoercion)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MCoercion -> m MCoercion)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MCoercion -> m MCoercion)
-> Data MCoercion
MCoercion -> DataType
MCoercion -> Constr
(forall b. Data b => b -> b) -> MCoercion -> MCoercion
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MCoercion -> c MCoercion
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MCoercion
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> MCoercion -> u
forall u. (forall d. Data d => d -> u) -> MCoercion -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MCoercion -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MCoercion -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MCoercion
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MCoercion -> c MCoercion
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MCoercion)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MCoercion)
$cMCo :: Constr
$cMRefl :: Constr
$tMCoercion :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
gmapMp :: (forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
gmapM :: (forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MCoercion -> m MCoercion
gmapQi :: Int -> (forall d. Data d => d -> u) -> MCoercion -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MCoercion -> u
gmapQ :: (forall d. Data d => d -> u) -> MCoercion -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MCoercion -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MCoercion -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MCoercion -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MCoercion -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MCoercion -> r
gmapT :: (forall b. Data b => b -> b) -> MCoercion -> MCoercion
$cgmapT :: (forall b. Data b => b -> b) -> MCoercion -> MCoercion
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MCoercion)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MCoercion)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c MCoercion)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MCoercion)
dataTypeOf :: MCoercion -> DataType
$cdataTypeOf :: MCoercion -> DataType
toConstr :: MCoercion -> Constr
$ctoConstr :: MCoercion -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MCoercion
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MCoercion
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MCoercion -> c MCoercion
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MCoercion -> c MCoercion
$cp1Data :: Typeable MCoercion
Data.Data
type MCoercionR = MCoercion
type MCoercionN = MCoercion

instance Outputable MCoercion where
  ppr :: MCoercion -> SDoc
ppr MCoercion
MRefl    = String -> SDoc
text String
"MRefl"
  ppr (MCo Coercion
co) = String -> SDoc
text String
"MCo" SDoc -> SDoc -> SDoc
<+> Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr Coercion
co

{-
Note [Refl invariant]
~~~~~~~~~~~~~~~~~~~~~
Invariant 1:

Coercions have the following invariant
     Refl (similar for GRefl r ty MRefl) is always lifted as far as possible.

You might think that a consequencs is:
     Every identity coercions has Refl at the root

But that's not quite true because of coercion variables.  Consider
     g         where g :: Int~Int
     Left h    where h :: Maybe Int ~ Maybe Int
etc.  So the consequence is only true of coercions that
have no coercion variables.

Note [Generalized reflexive coercion]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

GRefl is a generalized reflexive coercion (see Trac #15192). It wraps a kind
coercion, which might be reflexive (MRefl) or any coercion (MCo co). The typing
rules for GRefl:

  ty : k1
  ------------------------------------
  GRefl r ty MRefl: ty ~r ty

  ty : k1       co :: k1 ~ k2
  ------------------------------------
  GRefl r ty (MCo co) : ty ~r ty |> co

Consider we have

   g1 :: s ~r t
   s  :: k1
   g2 :: k1 ~ k2

and we want to construct a coercions co which has type

   (s |> g2) ~r t

We can define

   co = Sym (GRefl r s g2) ; g1

It is easy to see that

   Refl == GRefl Nominal ty MRefl :: ty ~n ty

A nominal reflexive coercion is quite common, so we keep the special form Refl to
save allocation.

Note [Coercion axioms applied to coercions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reason coercion axioms can be applied to coercions and not just
types is to allow for better optimization.  There are some cases where
we need to be able to "push transitivity inside" an axiom in order to
expose further opportunities for optimization.

For example, suppose we have

  C a : t[a] ~ F a
  g   : b ~ c

and we want to optimize

  sym (C b) ; t[g] ; C c

which has the kind

  F b ~ F c

(stopping through t[b] and t[c] along the way).

We'd like to optimize this to just F g -- but how?  The key is
that we need to allow axioms to be instantiated by *coercions*,
not just by types.  Then we can (in certain cases) push
transitivity inside the axiom instantiations, and then react
opposite-polarity instantiations of the same axiom.  In this
case, e.g., we match t[g] against the LHS of (C c)'s kind, to
obtain the substitution  a |-> g  (note this operation is sort
of the dual of lifting!) and hence end up with

  C g : t[b] ~ F c

which indeed has the same kind as  t[g] ; C c.

Now we have

  sym (C b) ; C g

which can be optimized to F g.

Note [CoAxiom index]
~~~~~~~~~~~~~~~~~~~~
A CoAxiom has 1 or more branches. Each branch has contains a list
of the free type variables in that branch, the LHS type patterns,
and the RHS type for that branch. When we apply an axiom to a list
of coercions, we must choose which branch of the axiom we wish to
use, as the different branches may have different numbers of free
type variables. (The number of type patterns is always the same
among branches, but that doesn't quite concern us here.)

The Int in the AxiomInstCo constructor is the 0-indexed number
of the chosen branch.

Note [Forall coercions]
~~~~~~~~~~~~~~~~~~~~~~~
Constructing coercions between forall-types can be a bit tricky,
because the kinds of the bound tyvars can be different.

The typing rule is:


  kind_co : k1 ~ k2
  tv1:k1 |- co : t1 ~ t2
  -------------------------------------------------------------------
  ForAllCo tv1 kind_co co : all tv1:k1. t1  ~
                            all tv1:k2. (t2[tv1 |-> tv1 |> sym kind_co])

First, the TyCoVar stored in a ForAllCo is really an optimisation: this field
should be a Name, as its kind is redundant. Thinking of the field as a Name
is helpful in understanding what a ForAllCo means.
The kind of TyCoVar always matches the left-hand kind of the coercion.

The idea is that kind_co gives the two kinds of the tyvar. See how, in the
conclusion, tv1 is assigned kind k1 on the left but kind k2 on the right.

Of course, a type variable can't have different kinds at the same time. So,
we arbitrarily prefer the first kind when using tv1 in the inner coercion
co, which shows that t1 equals t2.

The last wrinkle is that we need to fix the kinds in the conclusion. In
t2, tv1 is assumed to have kind k1, but it has kind k2 in the conclusion of
the rule. So we do a kind-fixing substitution, replacing (tv1:k1) with
(tv1:k2) |> sym kind_co. This substitution is slightly bizarre, because it
mentions the same name with different kinds, but it *is* well-kinded, noting
that `(tv1:k2) |> sym kind_co` has kind k1.

This all really would work storing just a Name in the ForAllCo. But we can't
add Names to, e.g., VarSets, and there generally is just an impedance mismatch
in a bunch of places. So we use tv1. When we need tv2, we can use
setTyVarKind.

Note [Predicate coercions]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose we have
   g :: a~b
How can we coerce between types
   ([c]~a) => [a] -> c
and
   ([c]~b) => [b] -> c
where the equality predicate *itself* differs?

Answer: we simply treat (~) as an ordinary type constructor, so these
types really look like

   ((~) [c] a) -> [a] -> c
   ((~) [c] b) -> [b] -> c

So the coercion between the two is obviously

   ((~) [c] g) -> [g] -> c

Another way to see this to say that we simply collapse predicates to
their representation type (see Type.coreView and Type.predTypeRep).

This collapse is done by mkPredCo; there is no PredCo constructor
in Coercion.  This is important because we need Nth to work on
predicates too:
    Nth 1 ((~) [c] g) = g
See Simplify.simplCoercionF, which generates such selections.

Note [Roles]
~~~~~~~~~~~~
Roles are a solution to the GeneralizedNewtypeDeriving problem, articulated
in Trac #1496. The full story is in docs/core-spec/core-spec.pdf. Also, see
http://ghc.haskell.org/trac/ghc/wiki/RolesImplementation

Here is one way to phrase the problem:

Given:
newtype Age = MkAge Int
type family F x
type instance F Age = Bool
type instance F Int = Char

This compiles down to:
axAge :: Age ~ Int
axF1 :: F Age ~ Bool
axF2 :: F Int ~ Char

Then, we can make:
(sym (axF1) ; F axAge ; axF2) :: Bool ~ Char

Yikes!

The solution is _roles_, as articulated in "Generative Type Abstraction and
Type-level Computation" (POPL 2010), available at
http://www.seas.upenn.edu/~sweirich/papers/popl163af-weirich.pdf

The specification for roles has evolved somewhat since that paper. For the
current full details, see the documentation in docs/core-spec. Here are some
highlights.

We label every equality with a notion of type equivalence, of which there are
three options: Nominal, Representational, and Phantom. A ground type is
nominally equivalent only with itself. A newtype (which is considered a ground
type in Haskell) is representationally equivalent to its representation.
Anything is "phantomly" equivalent to anything else. We use "N", "R", and "P"
to denote the equivalences.

The axioms above would be:
axAge :: Age ~R Int
axF1 :: F Age ~N Bool
axF2 :: F Age ~N Char

Then, because transitivity applies only to coercions proving the same notion
of equivalence, the above construction is impossible.

However, there is still an escape hatch: we know that any two types that are
nominally equivalent are representationally equivalent as well. This is what
the form SubCo proves -- it "demotes" a nominal equivalence into a
representational equivalence. So, it would seem the following is possible:

sub (sym axF1) ; F axAge ; sub axF2 :: Bool ~R Char   -- WRONG

What saves us here is that the arguments to a type function F, lifted into a
coercion, *must* prove nominal equivalence. So, (F axAge) is ill-formed, and
we are safe.

Roles are attached to parameters to TyCons. When lifting a TyCon into a
coercion (through TyConAppCo), we need to ensure that the arguments to the
TyCon respect their roles. For example:

data T a b = MkT a (F b)

If we know that a1 ~R a2, then we know (T a1 b) ~R (T a2 b). But, if we know
that b1 ~R b2, we know nothing about (T a b1) and (T a b2)! This is because
the type function F branches on b's *name*, not representation. So, we say
that 'a' has role Representational and 'b' has role Nominal. The third role,
Phantom, is for parameters not used in the type's definition. Given the
following definition

data Q a = MkQ Int

the Phantom role allows us to say that (Q Bool) ~R (Q Char), because we
can construct the coercion Bool ~P Char (using UnivCo).

See the paper cited above for more examples and information.

Note [TyConAppCo roles]
~~~~~~~~~~~~~~~~~~~~~~~
The TyConAppCo constructor has a role parameter, indicating the role at
which the coercion proves equality. The choice of this parameter affects
the required roles of the arguments of the TyConAppCo. To help explain
it, assume the following definition:

  type instance F Int = Bool   -- Axiom axF : F Int ~N Bool
  newtype Age = MkAge Int      -- Axiom axAge : Age ~R Int
  data Foo a = MkFoo a         -- Role on Foo's parameter is Representational

TyConAppCo Nominal Foo axF : Foo (F Int) ~N Foo Bool
  For (TyConAppCo Nominal) all arguments must have role Nominal. Why?
  So that Foo Age ~N Foo Int does *not* hold.

TyConAppCo Representational Foo (SubCo axF) : Foo (F Int) ~R Foo Bool
TyConAppCo Representational Foo axAge       : Foo Age     ~R Foo Int
  For (TyConAppCo Representational), all arguments must have the roles
  corresponding to the result of tyConRoles on the TyCon. This is the
  whole point of having roles on the TyCon to begin with. So, we can
  have Foo Age ~R Foo Int, if Foo's parameter has role R.

  If a Representational TyConAppCo is over-saturated (which is otherwise fine),
  the spill-over arguments must all be at Nominal. This corresponds to the
  behavior for AppCo.

TyConAppCo Phantom Foo (UnivCo Phantom Int Bool) : Foo Int ~P Foo Bool
  All arguments must have role Phantom. This one isn't strictly
  necessary for soundness, but this choice removes ambiguity.

The rules here dictate the roles of the parameters to mkTyConAppCo
(should be checked by Lint).

Note [NthCo and newtypes]
~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose we have

  newtype N a = MkN Int
  type role N representational

This yields axiom

  NTCo:N :: forall a. N a ~R Int

We can then build

  co :: forall a b. N a ~R N b
  co = NTCo:N a ; sym (NTCo:N b)

for any `a` and `b`. Because of the role annotation on N, if we use
NthCo, we'll get out a representational coercion. That is:

  NthCo r 0 co :: forall a b. a ~R b

Yikes! Clearly, this is terrible. The solution is simple: forbid
NthCo to be used on newtypes if the internal coercion is representational.

This is not just some corner case discovered by a segfault somewhere;
it was discovered in the proof of soundness of roles and described
in the "Safe Coercions" paper (ICFP '14).

Note [NthCo Cached Roles]
~~~~~~~~~~~~~~~~~~~~~~~~~
Why do we cache the role of NthCo in the NthCo constructor?
Because computing role(Nth i co) involves figuring out that

  co :: T tys1 ~ T tys2

using coercionKind, and finding (coercionRole co), and then looking
at the tyConRoles of T. Avoiding bad asymptotic behaviour here means
we have to compute the kind and role of a coercion simultaneously,
which makes the code complicated and inefficient.

This only happens for NthCo. Caching the role solves the problem, and
allows coercionKind and coercionRole to be simple.

See Trac #11735

Note [InstCo roles]
~~~~~~~~~~~~~~~~~~~
Here is (essentially) the typing rule for InstCo:

g :: (forall a. t1) ~r (forall a. t2)
w :: s1 ~N s2
------------------------------- InstCo
InstCo g w :: (t1 [a |-> s1]) ~r (t2 [a |-> s2])

Note that the Coercion w *must* be nominal. This is necessary
because the variable a might be used in a "nominal position"
(that is, a place where role inference would require a nominal
role) in t1 or t2. If we allowed w to be representational, we
could get bogus equalities.

A more nuanced treatment might be able to relax this condition
somewhat, by checking if t1 and/or t2 use their bound variables
in nominal ways. If not, having w be representational is OK.


%************************************************************************
%*                                                                      *
                UnivCoProvenance
%*                                                                      *
%************************************************************************

A UnivCo is a coercion whose proof does not directly express its role
and kind (indeed for some UnivCos, like UnsafeCoerceProv, there /is/
no proof).

The different kinds of UnivCo are described by UnivCoProvenance.  Really
each is entirely separate, but they all share the need to represent their
role and kind, which is done in the UnivCo constructor.

-}

-- | For simplicity, we have just one UnivCo that represents a coercion from
-- some type to some other type, with (in general) no restrictions on the
-- type. The UnivCoProvenance specifies more exactly what the coercion really
-- is and why a program should (or shouldn't!) trust the coercion.
-- It is reasonable to consider each constructor of 'UnivCoProvenance'
-- as a totally independent coercion form; their only commonality is
-- that they don't tell you what types they coercion between. (That info
-- is in the 'UnivCo' constructor of 'Coercion'.
data UnivCoProvenance
  = UnsafeCoerceProv   -- ^ From @unsafeCoerce#@. These are unsound.

  | PhantomProv KindCoercion -- ^ See Note [Phantom coercions]. Only in Phantom
                             -- roled coercions

  | ProofIrrelProv KindCoercion  -- ^ From the fact that any two coercions are
                                 --   considered equivalent. See Note [ProofIrrelProv].
                                 -- Can be used in Nominal or Representational coercions

  | PluginProv String  -- ^ From a plugin, which asserts that this coercion
                       --   is sound. The string is for the use of the plugin.

  deriving Typeable UnivCoProvenance
DataType
Constr
Typeable UnivCoProvenance
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UnivCoProvenance -> c UnivCoProvenance)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UnivCoProvenance)
-> (UnivCoProvenance -> Constr)
-> (UnivCoProvenance -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UnivCoProvenance))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c UnivCoProvenance))
-> ((forall b. Data b => b -> b)
    -> UnivCoProvenance -> UnivCoProvenance)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> UnivCoProvenance -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> UnivCoProvenance -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> UnivCoProvenance -> m UnivCoProvenance)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> UnivCoProvenance -> m UnivCoProvenance)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> UnivCoProvenance -> m UnivCoProvenance)
-> Data UnivCoProvenance
UnivCoProvenance -> DataType
UnivCoProvenance -> Constr
(forall b. Data b => b -> b)
-> UnivCoProvenance -> UnivCoProvenance
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnivCoProvenance -> c UnivCoProvenance
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnivCoProvenance
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> UnivCoProvenance -> u
forall u. (forall d. Data d => d -> u) -> UnivCoProvenance -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnivCoProvenance
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnivCoProvenance -> c UnivCoProvenance
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnivCoProvenance)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c UnivCoProvenance)
$cPluginProv :: Constr
$cProofIrrelProv :: Constr
$cPhantomProv :: Constr
$cUnsafeCoerceProv :: Constr
$tUnivCoProvenance :: DataType
gmapMo :: (forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
gmapMp :: (forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
gmapM :: (forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> UnivCoProvenance -> m UnivCoProvenance
gmapQi :: Int -> (forall d. Data d => d -> u) -> UnivCoProvenance -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> UnivCoProvenance -> u
gmapQ :: (forall d. Data d => d -> u) -> UnivCoProvenance -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UnivCoProvenance -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnivCoProvenance -> r
gmapT :: (forall b. Data b => b -> b)
-> UnivCoProvenance -> UnivCoProvenance
$cgmapT :: (forall b. Data b => b -> b)
-> UnivCoProvenance -> UnivCoProvenance
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c UnivCoProvenance)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c UnivCoProvenance)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c UnivCoProvenance)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnivCoProvenance)
dataTypeOf :: UnivCoProvenance -> DataType
$cdataTypeOf :: UnivCoProvenance -> DataType
toConstr :: UnivCoProvenance -> Constr
$ctoConstr :: UnivCoProvenance -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnivCoProvenance
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnivCoProvenance
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnivCoProvenance -> c UnivCoProvenance
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnivCoProvenance -> c UnivCoProvenance
$cp1Data :: Typeable UnivCoProvenance
Data.Data

instance Outputable UnivCoProvenance where
  ppr :: UnivCoProvenance -> SDoc
ppr UnivCoProvenance
UnsafeCoerceProv   = String -> SDoc
text String
"(unsafeCoerce#)"
  ppr (PhantomProv Coercion
_)    = String -> SDoc
text String
"(phantom)"
  ppr (ProofIrrelProv Coercion
_) = String -> SDoc
text String
"(proof irrel.)"
  ppr (PluginProv String
str)   = SDoc -> SDoc
parens (String -> SDoc
text String
"plugin" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
brackets (String -> SDoc
text String
str))

-- | A coercion to be filled in by the type-checker. See Note [Coercion holes]
data CoercionHole
  = CoercionHole { CoercionHole -> Id
ch_co_var :: CoVar
                       -- See Note [CoercionHoles and coercion free variables]

                 , CoercionHole -> IORef (Maybe Coercion)
ch_ref    :: IORef (Maybe Coercion)
                 }

coHoleCoVar :: CoercionHole -> CoVar
coHoleCoVar :: CoercionHole -> Id
coHoleCoVar = CoercionHole -> Id
ch_co_var

setCoHoleCoVar :: CoercionHole -> CoVar -> CoercionHole
setCoHoleCoVar :: CoercionHole -> Id -> CoercionHole
setCoHoleCoVar CoercionHole
h Id
cv = CoercionHole
h { ch_co_var :: Id
ch_co_var = Id
cv }

instance Data.Data CoercionHole where
  -- don't traverse?
  toConstr :: CoercionHole -> Constr
toConstr CoercionHole
_   = String -> Constr
abstractConstr String
"CoercionHole"
  gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CoercionHole
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
_  = String -> Constr -> c CoercionHole
forall a. HasCallStack => String -> a
error String
"gunfold"
  dataTypeOf :: CoercionHole -> DataType
dataTypeOf CoercionHole
_ = String -> DataType
mkNoRepType String
"CoercionHole"

instance Outputable CoercionHole where
  ppr :: CoercionHole -> SDoc
ppr (CoercionHole { ch_co_var :: CoercionHole -> Id
ch_co_var = Id
cv }) = SDoc -> SDoc
braces (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
cv)


{- Note [Phantom coercions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
     data T a = T1 | T2
Then we have
     T s ~R T t
for any old s,t. The witness for this is (TyConAppCo T Rep co),
where (co :: s ~P t) is a phantom coercion built with PhantomProv.
The role of the UnivCo is always Phantom.  The Coercion stored is the
(nominal) kind coercion between the types
   kind(s) ~N kind (t)

Note [Coercion holes]
~~~~~~~~~~~~~~~~~~~~~~~~
During typechecking, constraint solving for type classes works by
  - Generate an evidence Id,  d7 :: Num a
  - Wrap it in a Wanted constraint, [W] d7 :: Num a
  - Use the evidence Id where the evidence is needed
  - Solve the constraint later
  - When solved, add an enclosing let-binding  let d7 = .... in ....
    which actually binds d7 to the (Num a) evidence

For equality constraints we use a different strategy.  See Note [The
equality types story] in TysPrim for background on equality constraints.
  - For /boxed/ equality constraints, (t1 ~N t2) and (t1 ~R t2), it's just
    like type classes above. (Indeed, boxed equality constraints *are* classes.)
  - But for /unboxed/ equality constraints (t1 ~R# t2) and (t1 ~N# t2)
    we use a different plan

For unboxed equalities:
  - Generate a CoercionHole, a mutable variable just like a unification
    variable
  - Wrap the CoercionHole in a Wanted constraint; see TcRnTypes.TcEvDest
  - Use the CoercionHole in a Coercion, via HoleCo
  - Solve the constraint later
  - When solved, fill in the CoercionHole by side effect, instead of
    doing the let-binding thing

The main reason for all this is that there may be no good place to let-bind
the evidence for unboxed equalities:

  - We emit constraints for kind coercions, to be used to cast a
    type's kind. These coercions then must be used in types. Because
    they might appear in a top-level type, there is no place to bind
    these (unlifted) coercions in the usual way.

  - A coercion for (forall a. t1) ~ (forall a. t2) will look like
       forall a. (coercion for t1~t2)
    But the coercion for (t1~t2) may mention 'a', and we don't have
    let-bindings within coercions.  We could add them, but coercion
    holes are easier.

  - Moreover, nothing is lost from the lack of let-bindings. For
    dicionaries want to achieve sharing to avoid recomoputing the
    dictionary.  But coercions are entirely erased, so there's little
    benefit to sharing. Indeed, even if we had a let-binding, we
    always inline types and coercions at every use site and drop the
    binding.

Other notes about HoleCo:

 * INVARIANT: CoercionHole and HoleCo are used only during type checking,
   and should never appear in Core. Just like unification variables; a Type
   can contain a TcTyVar, but only during type checking. If, one day, we
   use type-level information to separate out forms that can appear during
   type-checking vs forms that can appear in core proper, holes in Core will
   be ruled out.

 * See Note [CoercionHoles and coercion free variables]

 * Coercion holes can be compared for equality like other coercions:
   by looking at the types coerced.


Note [CoercionHoles and coercion free variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Why does a CoercionHole contain a CoVar, as well as reference to
fill in?  Because we want to treat that CoVar as a free variable of
the coercion.  See Trac #14584, and Note [What prevents a
constraint from floating] in TcSimplify, item (4):

        forall k. [W] co1 :: t1 ~# t2 |> co2
                  [W] co2 :: k ~# *

Here co2 is a CoercionHole. But we /must/ know that it is free in
co1, because that's all that stops it floating outside the
implication.


Note [ProofIrrelProv]
~~~~~~~~~~~~~~~~~~~~~
A ProofIrrelProv is a coercion between coercions. For example:

  data G a where
    MkG :: G Bool

In core, we get

  G :: * -> *
  MkG :: forall (a :: *). (a ~ Bool) -> G a

Now, consider 'MkG -- that is, MkG used in a type -- and suppose we want
a proof that ('MkG a1 co1) ~ ('MkG a2 co2). This will have to be

  TyConAppCo Nominal MkG [co3, co4]
  where
    co3 :: co1 ~ co2
    co4 :: a1 ~ a2

Note that
  co1 :: a1 ~ Bool
  co2 :: a2 ~ Bool

Here,
  co3 = UnivCo (ProofIrrelProv co5) Nominal (CoercionTy co1) (CoercionTy co2)
  where
    co5 :: (a1 ~ Bool) ~ (a2 ~ Bool)
    co5 = TyConAppCo Nominal (~#) [<*>, <*>, co4, <Bool>]


%************************************************************************
%*                                                                      *
                 Free variables of types and coercions
%*                                                                      *
%************************************************************************
-}

{- Note [Free variables of types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The family of functions tyCoVarsOfType, tyCoVarsOfTypes etc, returns
a VarSet that is closed over the types of its variables.  More precisely,
  if    S = tyCoVarsOfType( t )
  and   (a:k) is in S
  then  tyCoVarsOftype( k ) is a subset of S

Example: The tyCoVars of this ((a:* -> k) Int) is {a, k}.

We could /not/ close over the kinds of the variable occurrences, and
instead do so at call sites, but it seems that we always want to do
so, so it's easiest to do it here.

It turns out that getting the free variables of types is performance critical,
so we profiled several versions, exploring different implementation strategies.

1. Baseline version: uses FV naively. Essentially:

   tyCoVarsOfType ty = fvVarSet $ tyCoFVsOfType ty

   This is not nice, because FV introduces some overhead to implement
   determinism, and throught its "interesting var" function, neither of which
   we need here, so they are a complete waste.

2. UnionVarSet version: instead of reusing the FV-based code, we simply used
   VarSets directly, trying to avoid the overhead of FV. E.g.:

   -- FV version:
   tyCoFVsOfType (AppTy fun arg)    a b c = (tyCoFVsOfType fun `unionFV` tyCoFVsOfType arg) a b c

   -- UnionVarSet version:
   tyCoVarsOfType (AppTy fun arg)    = (tyCoVarsOfType fun `unionVarSet` tyCoVarsOfType arg)

   This looks deceptively similar, but while FV internally builds a list- and
   set-generating function, the VarSet functions manipulate sets directly, and
   the latter peforms a lot worse than the naive FV version.

3. Accumulator-style VarSet version: this is what we use now. We do use VarSet
   as our data structure, but delegate the actual work to a new
   ty_co_vars_of_...  family of functions, which use accumulator style and the
   "in-scope set" filter found in the internals of FV, but without the
   determinism overhead.

See Trac #14880.

Note [Closing over free variable kinds]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tyCoVarsOfType and tyCoFVsOfType, while traversing a type, will also close over
free variable kinds. In previous GHC versions, this happened naively: whenever
we would encounter an occurrence of a free type variable, we would close over
its kind. This, however is wrong for two reasons (see Trac #14880):

1. Efficiency. If we have Proxy (a::k) -> Proxy (a::k) -> Proxy (a::k), then
   we don't want to have to traverse k more than once.

2. Correctness. Imagine we have forall k. b -> k, where b has
   kind k, for some k bound in an outer scope. If we look at b's kind inside
   the forall, we'll collect that k is free and then remove k from the set of
   free variables. This is plain wrong. We must instead compute that b is free
   and then conclude that b's kind is free.

An obvious first approach is to move the closing-over-kinds from the
occurrences of a type variable to after finding the free vars - however, this
turns out to introduce performance regressions, and isn't even entirely
correct.

In fact, it isn't even important *when* we close over kinds; what matters is
that we handle each type var exactly once, and that we do it in the right
context.

So the next approach we tried was to use the "in-scope set" part of FV or the
equivalent argument in the accumulator-style `ty_co_vars_of_type` function, to
say "don't bother with variables we have already closed over". This should work
fine in theory, but the code is complicated and doesn't perform well.

But there is a simpler way, which is implemented here. Consider the two points
above:

1. Efficiency: we now have an accumulator, so the second time we encounter 'a',
   we'll ignore it, certainly not looking at its kind - this is why
   pre-checking set membership before inserting ends up not only being faster,
   but also being correct.

2. Correctness: we have an "in-scope set" (I think we should call it it a
  "bound-var set"), specifying variables that are bound by a forall in the type
  we are traversing; we simply ignore these variables, certainly not looking at
  their kind.

So now consider:

    forall k. b -> k

where b :: k->Type is free; but of course, it's a different k! When looking at
b -> k we'll have k in the bound-var set. So we'll ignore the k. But suppose
this is our first encounter with b; we want the free vars of its kind. But we
want to behave as if we took the free vars of its kind at the end; that is,
with no bound vars in scope.

So the solution is easy. The old code was this:

  ty_co_vars_of_type (TyVarTy v) is acc
    | v `elemVarSet` is  = acc
    | v `elemVarSet` acc = acc
    | otherwise          = ty_co_vars_of_type (tyVarKind v) is (extendVarSet acc v)

Now all we need to do is take the free vars of tyVarKind v *with an empty
bound-var set*, thus:

ty_co_vars_of_type (TyVarTy v) is acc
  | v `elemVarSet` is  = acc
  | v `elemVarSet` acc = acc
  | otherwise          = ty_co_vars_of_type (tyVarKind v) emptyVarSet (extendVarSet acc v)
                                                          ^^^^^^^^^^^

And that's it.

-}

tyCoVarsOfType :: Type -> TyCoVarSet
-- See Note [Free variables of types]
tyCoVarsOfType :: Type -> VarSet
tyCoVarsOfType Type
ty = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
ty VarSet
emptyVarSet VarSet
emptyVarSet

tyCoVarsOfTypes :: [Type] -> TyCoVarSet
tyCoVarsOfTypes :: [Type] -> VarSet
tyCoVarsOfTypes [Type]
tys = [Type] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_types [Type]
tys VarSet
emptyVarSet VarSet
emptyVarSet

ty_co_vars_of_type :: Type -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_type :: Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type (TyVarTy Id
v) VarSet
is VarSet
acc
  | Id
v Id -> VarSet -> Bool
`elemVarSet` VarSet
is  = VarSet
acc
  | Id
v Id -> VarSet -> Bool
`elemVarSet` VarSet
acc = VarSet
acc
  | Bool
otherwise          = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type (Id -> Type
tyVarKind Id
v)
                            VarSet
emptyVarSet  -- See Note [Closing over free variable kinds]
                            (VarSet -> Id -> VarSet
extendVarSet VarSet
acc Id
v)

ty_co_vars_of_type (TyConApp TyCon
_ [Type]
tys)   VarSet
is VarSet
acc = [Type] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_types [Type]
tys VarSet
is VarSet
acc
ty_co_vars_of_type (LitTy {})         VarSet
_  VarSet
acc = VarSet
acc
ty_co_vars_of_type (AppTy Type
fun Type
arg)    VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
fun VarSet
is (Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
arg VarSet
is VarSet
acc)
ty_co_vars_of_type (FunTy Type
arg Type
res)    VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
arg VarSet
is (Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
res VarSet
is VarSet
acc)
ty_co_vars_of_type (ForAllTy (Bndr Id
tv ArgFlag
_) Type
ty) VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type (Id -> Type
varType Id
tv) VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                                      Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
ty (VarSet -> Id -> VarSet
extendVarSet VarSet
is Id
tv) VarSet
acc
ty_co_vars_of_type (CastTy Type
ty Coercion
co)     VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
ty VarSet
is (Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc)
ty_co_vars_of_type (CoercionTy Coercion
co)    VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc

ty_co_vars_of_types :: [Type] -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_types :: [Type] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_types []       VarSet
_  VarSet
acc = VarSet
acc
ty_co_vars_of_types (Type
ty:[Type]
tys) VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
ty VarSet
is ([Type] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_types [Type]
tys VarSet
is VarSet
acc)

tyCoVarsOfCo :: Coercion -> TyCoVarSet
-- See Note [Free variables of types]
tyCoVarsOfCo :: Coercion -> VarSet
tyCoVarsOfCo Coercion
co = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
emptyVarSet VarSet
emptyVarSet

tyCoVarsOfCos :: [Coercion] -> TyCoVarSet
tyCoVarsOfCos :: [Coercion] -> VarSet
tyCoVarsOfCos [Coercion]
cos = [Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos [Coercion]
cos VarSet
emptyVarSet VarSet
emptyVarSet


ty_co_vars_of_co :: Coercion -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_co :: Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co (Refl Type
ty)            VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
ty VarSet
is VarSet
acc
ty_co_vars_of_co (GRefl Role
_ Type
ty MCoercion
mco)     VarSet
is VarSet
acc = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
ty VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                               MCoercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_mco MCoercion
mco VarSet
is VarSet
acc
ty_co_vars_of_co (TyConAppCo Role
_ TyCon
_ [Coercion]
cos) VarSet
is VarSet
acc = [Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos [Coercion]
cos VarSet
is VarSet
acc
ty_co_vars_of_co (AppCo Coercion
co Coercion
arg)       VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                               Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
arg VarSet
is VarSet
acc
ty_co_vars_of_co (ForAllCo Id
tv Coercion
kind_co Coercion
co) VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
kind_co VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                                   Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co (VarSet -> Id -> VarSet
extendVarSet VarSet
is Id
tv) VarSet
acc
ty_co_vars_of_co (FunCo Role
_ Coercion
co1 Coercion
co2)    VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co1 VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                               Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co2 VarSet
is VarSet
acc
ty_co_vars_of_co (CoVarCo Id
v)          VarSet
is VarSet
acc = Id -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co_var Id
v VarSet
is VarSet
acc
ty_co_vars_of_co (HoleCo CoercionHole
h)           VarSet
is VarSet
acc = Id -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co_var (CoercionHole -> Id
coHoleCoVar CoercionHole
h) VarSet
is VarSet
acc
    -- See Note [CoercionHoles and coercion free variables]
ty_co_vars_of_co (AxiomInstCo CoAxiom Branched
_ Int
_ [Coercion]
cos) VarSet
is VarSet
acc = [Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos [Coercion]
cos VarSet
is VarSet
acc
ty_co_vars_of_co (UnivCo UnivCoProvenance
p Role
_ Type
t1 Type
t2)    VarSet
is VarSet
acc = UnivCoProvenance -> VarSet -> VarSet -> VarSet
ty_co_vars_of_prov UnivCoProvenance
p VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                                Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
t1 VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                                Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type Type
t2 VarSet
is VarSet
acc
ty_co_vars_of_co (SymCo Coercion
co)          VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_co (TransCo Coercion
co1 Coercion
co2)   VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co1 VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                              Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co2 VarSet
is VarSet
acc
ty_co_vars_of_co (NthCo Role
_ Int
_ Coercion
co)      VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_co (LRCo LeftOrRight
_ Coercion
co)         VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_co (InstCo Coercion
co Coercion
arg)     VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                                              Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
arg VarSet
is VarSet
acc
ty_co_vars_of_co (KindCo Coercion
co)         VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_co (SubCo Coercion
co)          VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_co (AxiomRuleCo CoAxiomRule
_ [Coercion]
cs)  VarSet
is VarSet
acc = [Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos [Coercion]
cs VarSet
is VarSet
acc

ty_co_vars_of_mco :: MCoercion -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_mco :: MCoercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_mco MCoercion
MRefl    VarSet
_is VarSet
acc = VarSet
acc
ty_co_vars_of_mco (MCo Coercion
co) VarSet
is  VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc

ty_co_vars_of_co_var :: CoVar -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_co_var :: Id -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co_var Id
v VarSet
is VarSet
acc
  | Id
v Id -> VarSet -> Bool
`elemVarSet` VarSet
is  = VarSet
acc
  | Id
v Id -> VarSet -> Bool
`elemVarSet` VarSet
acc = VarSet
acc
  | Bool
otherwise          = Type -> VarSet -> VarSet -> VarSet
ty_co_vars_of_type (Id -> Type
varType Id
v)
                            VarSet
emptyVarSet  -- See Note [Closing over free variable kinds]
                            (VarSet -> Id -> VarSet
extendVarSet VarSet
acc Id
v)

ty_co_vars_of_cos :: [Coercion] -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_cos :: [Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos []       VarSet
_  VarSet
acc = VarSet
acc
ty_co_vars_of_cos (Coercion
co:[Coercion]
cos) VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is ([Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos [Coercion]
cos VarSet
is VarSet
acc)

tyCoVarsOfProv :: UnivCoProvenance -> TyCoVarSet
tyCoVarsOfProv :: UnivCoProvenance -> VarSet
tyCoVarsOfProv UnivCoProvenance
prov = UnivCoProvenance -> VarSet -> VarSet -> VarSet
ty_co_vars_of_prov UnivCoProvenance
prov VarSet
emptyVarSet VarSet
emptyVarSet

ty_co_vars_of_prov :: UnivCoProvenance -> TyCoVarSet -> TyCoVarSet -> TyCoVarSet
ty_co_vars_of_prov :: UnivCoProvenance -> VarSet -> VarSet -> VarSet
ty_co_vars_of_prov (PhantomProv Coercion
co)    VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_prov (ProofIrrelProv Coercion
co) VarSet
is VarSet
acc = Coercion -> VarSet -> VarSet -> VarSet
ty_co_vars_of_co Coercion
co VarSet
is VarSet
acc
ty_co_vars_of_prov UnivCoProvenance
UnsafeCoerceProv    VarSet
_  VarSet
acc = VarSet
acc
ty_co_vars_of_prov (PluginProv String
_)      VarSet
_  VarSet
acc = VarSet
acc

-- | Generates an in-scope set from the free variables in a list of types
-- and a list of coercions
mkTyCoInScopeSet :: [Type] -> [Coercion] -> InScopeSet
mkTyCoInScopeSet :: [Type] -> [Coercion] -> InScopeSet
mkTyCoInScopeSet [Type]
tys [Coercion]
cos
  = VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_types [Type]
tys VarSet
emptyVarSet (VarSet -> VarSet) -> VarSet -> VarSet
forall a b. (a -> b) -> a -> b
$
                  [Coercion] -> VarSet -> VarSet -> VarSet
ty_co_vars_of_cos   [Coercion]
cos VarSet
emptyVarSet VarSet
emptyVarSet)

-- | `tyCoFVsOfType` that returns free variables of a type in a deterministic
-- set. For explanation of why using `VarSet` is not deterministic see
-- Note [Deterministic FV] in FV.
tyCoVarsOfTypeDSet :: Type -> DTyCoVarSet
-- See Note [Free variables of types]
tyCoVarsOfTypeDSet :: Type -> DTyCoVarSet
tyCoVarsOfTypeDSet Type
ty = FV -> DTyCoVarSet
fvDVarSet (FV -> DTyCoVarSet) -> FV -> DTyCoVarSet
forall a b. (a -> b) -> a -> b
$ Type -> FV
tyCoFVsOfType Type
ty

-- | `tyCoFVsOfType` that returns free variables of a type in deterministic
-- order. For explanation of why using `VarSet` is not deterministic see
-- Note [Deterministic FV] in FV.
tyCoVarsOfTypeList :: Type -> [TyCoVar]
-- See Note [Free variables of types]
tyCoVarsOfTypeList :: Type -> [Id]
tyCoVarsOfTypeList Type
ty = FV -> [Id]
fvVarList (FV -> [Id]) -> FV -> [Id]
forall a b. (a -> b) -> a -> b
$ Type -> FV
tyCoFVsOfType Type
ty

-- | Returns free variables of types, including kind variables as
-- a non-deterministic set. For type synonyms it does /not/ expand the
-- synonym.
tyCoVarsOfTypesSet :: TyVarEnv Type -> TyCoVarSet
-- See Note [Free variables of types]
tyCoVarsOfTypesSet :: TyVarEnv Type -> VarSet
tyCoVarsOfTypesSet TyVarEnv Type
tys = [Type] -> VarSet
tyCoVarsOfTypes ([Type] -> VarSet) -> [Type] -> VarSet
forall a b. (a -> b) -> a -> b
$ TyVarEnv Type -> [Type]
forall elt. UniqFM elt -> [elt]
nonDetEltsUFM TyVarEnv Type
tys
  -- It's OK to use nonDetEltsUFM here because we immediately forget the
  -- ordering by returning a set

-- | Returns free variables of types, including kind variables as
-- a deterministic set. For type synonyms it does /not/ expand the
-- synonym.
tyCoVarsOfTypesDSet :: [Type] -> DTyCoVarSet
-- See Note [Free variables of types]
tyCoVarsOfTypesDSet :: [Type] -> DTyCoVarSet
tyCoVarsOfTypesDSet [Type]
tys = FV -> DTyCoVarSet
fvDVarSet (FV -> DTyCoVarSet) -> FV -> DTyCoVarSet
forall a b. (a -> b) -> a -> b
$ [Type] -> FV
tyCoFVsOfTypes [Type]
tys

-- | Returns free variables of types, including kind variables as
-- a deterministically ordered list. For type synonyms it does /not/ expand the
-- synonym.
tyCoVarsOfTypesList :: [Type] -> [TyCoVar]
-- See Note [Free variables of types]
tyCoVarsOfTypesList :: [Type] -> [Id]
tyCoVarsOfTypesList [Type]
tys = FV -> [Id]
fvVarList (FV -> [Id]) -> FV -> [Id]
forall a b. (a -> b) -> a -> b
$ [Type] -> FV
tyCoFVsOfTypes [Type]
tys

-- | The worker for `tyCoFVsOfType` and `tyCoFVsOfTypeList`.
-- The previous implementation used `unionVarSet` which is O(n+m) and can
-- make the function quadratic.
-- It's exported, so that it can be composed with
-- other functions that compute free variables.
-- See Note [FV naming conventions] in FV.
--
-- Eta-expanded because that makes it run faster (apparently)
-- See Note [FV eta expansion] in FV for explanation.
tyCoFVsOfType :: Type -> FV
-- See Note [Free variables of types]
tyCoFVsOfType :: Type -> FV
tyCoFVsOfType (TyVarTy Id
v)        Id -> Bool
f VarSet
bound_vars ([Id]
acc_list, VarSet
acc_set)
  | Bool -> Bool
not (Id -> Bool
f Id
v) = ([Id]
acc_list, VarSet
acc_set)
  | Id
v Id -> VarSet -> Bool
`elemVarSet` VarSet
bound_vars = ([Id]
acc_list, VarSet
acc_set)
  | Id
v Id -> VarSet -> Bool
`elemVarSet` VarSet
acc_set = ([Id]
acc_list, VarSet
acc_set)
  | Bool
otherwise = Type -> FV
tyCoFVsOfType (Id -> Type
tyVarKind Id
v) Id -> Bool
f
                               VarSet
emptyVarSet   -- See Note [Closing over free variable kinds]
                               (Id
vId -> [Id] -> [Id]
forall a. a -> [a] -> [a]
:[Id]
acc_list, VarSet -> Id -> VarSet
extendVarSet VarSet
acc_set Id
v)
tyCoFVsOfType (TyConApp TyCon
_ [Type]
tys)   Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = [Type] -> FV
tyCoFVsOfTypes [Type]
tys Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc
tyCoFVsOfType (LitTy {})         Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = FV
emptyFV Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc
tyCoFVsOfType (AppTy Type
fun Type
arg)    Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = (Type -> FV
tyCoFVsOfType Type
fun FV -> FV -> FV
`unionFV` Type -> FV
tyCoFVsOfType Type
arg) Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc
tyCoFVsOfType (FunTy Type
arg Type
res)    Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = (Type -> FV
tyCoFVsOfType Type
arg FV -> FV -> FV
`unionFV` Type -> FV
tyCoFVsOfType Type
res) Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc
tyCoFVsOfType (ForAllTy TyCoVarBinder
bndr Type
ty) Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = TyCoVarBinder -> FV -> FV
tyCoFVsBndr TyCoVarBinder
bndr (Type -> FV
tyCoFVsOfType Type
ty)  Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc
tyCoFVsOfType (CastTy Type
ty Coercion
co)     Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = (Type -> FV
tyCoFVsOfType Type
ty FV -> FV -> FV
`unionFV` Coercion -> FV
tyCoFVsOfCo Coercion
co) Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc
tyCoFVsOfType (CoercionTy Coercion
co)    Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
f VarSet
bound_vars ([Id], VarSet)
acc

tyCoFVsBndr :: TyCoVarBinder -> FV -> FV
-- Free vars of (forall b. <thing with fvs>)
tyCoFVsBndr :: TyCoVarBinder -> FV -> FV
tyCoFVsBndr (Bndr Id
tv ArgFlag
_) FV
fvs = Id -> FV -> FV
tyCoFVsVarBndr Id
tv FV
fvs

tyCoFVsVarBndrs :: [Var] -> FV -> FV
tyCoFVsVarBndrs :: [Id] -> FV -> FV
tyCoFVsVarBndrs [Id]
vars FV
fvs = (Id -> FV -> FV) -> FV -> [Id] -> FV
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Id -> FV -> FV
tyCoFVsVarBndr FV
fvs [Id]
vars

tyCoFVsVarBndr :: Var -> FV -> FV
tyCoFVsVarBndr :: Id -> FV -> FV
tyCoFVsVarBndr Id
var FV
fvs
  = Type -> FV
tyCoFVsOfType (Id -> Type
varType Id
var)   -- Free vars of its type/kind
    FV -> FV -> FV
`unionFV` Id -> FV -> FV
delFV Id
var FV
fvs       -- Delete it from the thing-inside

tyCoFVsOfTypes :: [Type] -> FV
-- See Note [Free variables of types]
tyCoFVsOfTypes :: [Type] -> FV
tyCoFVsOfTypes (Type
ty:[Type]
tys) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = (Type -> FV
tyCoFVsOfType Type
ty FV -> FV -> FV
`unionFV` [Type] -> FV
tyCoFVsOfTypes [Type]
tys) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfTypes []       Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = FV
emptyFV Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc

-- | Get a deterministic set of the vars free in a coercion
tyCoVarsOfCoDSet :: Coercion -> DTyCoVarSet
-- See Note [Free variables of types]
tyCoVarsOfCoDSet :: Coercion -> DTyCoVarSet
tyCoVarsOfCoDSet Coercion
co = FV -> DTyCoVarSet
fvDVarSet (FV -> DTyCoVarSet) -> FV -> DTyCoVarSet
forall a b. (a -> b) -> a -> b
$ Coercion -> FV
tyCoFVsOfCo Coercion
co

tyCoVarsOfCoList :: Coercion -> [TyCoVar]
-- See Note [Free variables of types]
tyCoVarsOfCoList :: Coercion -> [Id]
tyCoVarsOfCoList Coercion
co = FV -> [Id]
fvVarList (FV -> [Id]) -> FV -> [Id]
forall a b. (a -> b) -> a -> b
$ Coercion -> FV
tyCoFVsOfCo Coercion
co

tyCoFVsOfMCo :: MCoercion -> FV
tyCoFVsOfMCo :: MCoercion -> FV
tyCoFVsOfMCo MCoercion
MRefl    = FV
emptyFV
tyCoFVsOfMCo (MCo Coercion
co) = Coercion -> FV
tyCoFVsOfCo Coercion
co

tyCoVarsOfCosSet :: CoVarEnv Coercion -> TyCoVarSet
tyCoVarsOfCosSet :: CoVarEnv Coercion -> VarSet
tyCoVarsOfCosSet CoVarEnv Coercion
cos = [Coercion] -> VarSet
tyCoVarsOfCos ([Coercion] -> VarSet) -> [Coercion] -> VarSet
forall a b. (a -> b) -> a -> b
$ CoVarEnv Coercion -> [Coercion]
forall elt. UniqFM elt -> [elt]
nonDetEltsUFM CoVarEnv Coercion
cos
  -- It's OK to use nonDetEltsUFM here because we immediately forget the
  -- ordering by returning a set

tyCoFVsOfCo :: Coercion -> FV
-- Extracts type and coercion variables from a coercion
-- See Note [Free variables of types]
tyCoFVsOfCo :: Coercion -> FV
tyCoFVsOfCo (Refl Type
ty) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = Type -> FV
tyCoFVsOfType Type
ty Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (GRefl Role
_ Type
ty MCoercion
mco) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = (Type -> FV
tyCoFVsOfType Type
ty FV -> FV -> FV
`unionFV` MCoercion -> FV
tyCoFVsOfMCo MCoercion
mco) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (TyConAppCo Role
_ TyCon
_ [Coercion]
cos) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = [Coercion] -> FV
tyCoFVsOfCos [Coercion]
cos Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (AppCo Coercion
co Coercion
arg) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = (Coercion -> FV
tyCoFVsOfCo Coercion
co FV -> FV -> FV
`unionFV` Coercion -> FV
tyCoFVsOfCo Coercion
arg) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (ForAllCo Id
tv Coercion
kind_co Coercion
co) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = (Id -> FV -> FV
tyCoFVsVarBndr Id
tv (Coercion -> FV
tyCoFVsOfCo Coercion
co) FV -> FV -> FV
`unionFV` Coercion -> FV
tyCoFVsOfCo Coercion
kind_co) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (FunCo Role
_ Coercion
co1 Coercion
co2)    Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = (Coercion -> FV
tyCoFVsOfCo Coercion
co1 FV -> FV -> FV
`unionFV` Coercion -> FV
tyCoFVsOfCo Coercion
co2) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (CoVarCo Id
v) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = Id -> FV
tyCoFVsOfCoVar Id
v Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (HoleCo CoercionHole
h) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = Id -> FV
tyCoFVsOfCoVar (CoercionHole -> Id
coHoleCoVar CoercionHole
h) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
    -- See Note [CoercionHoles and coercion free variables]
tyCoFVsOfCo (AxiomInstCo CoAxiom Branched
_ Int
_ [Coercion]
cos) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = [Coercion] -> FV
tyCoFVsOfCos [Coercion]
cos Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (UnivCo UnivCoProvenance
p Role
_ Type
t1 Type
t2) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = (UnivCoProvenance -> FV
tyCoFVsOfProv UnivCoProvenance
p FV -> FV -> FV
`unionFV` Type -> FV
tyCoFVsOfType Type
t1
                     FV -> FV -> FV
`unionFV` Type -> FV
tyCoFVsOfType Type
t2) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (SymCo Coercion
co)          Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (TransCo Coercion
co1 Coercion
co2)   Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = (Coercion -> FV
tyCoFVsOfCo Coercion
co1 FV -> FV -> FV
`unionFV` Coercion -> FV
tyCoFVsOfCo Coercion
co2) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (NthCo Role
_ Int
_ Coercion
co)      Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (LRCo LeftOrRight
_ Coercion
co)         Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (InstCo Coercion
co Coercion
arg)     Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = (Coercion -> FV
tyCoFVsOfCo Coercion
co FV -> FV -> FV
`unionFV` Coercion -> FV
tyCoFVsOfCo Coercion
arg) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (KindCo Coercion
co)         Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (SubCo Coercion
co)          Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCo (AxiomRuleCo CoAxiomRule
_ [Coercion]
cs)  Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = [Coercion] -> FV
tyCoFVsOfCos [Coercion]
cs Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc

tyCoFVsOfCoVar :: CoVar -> FV
tyCoFVsOfCoVar :: Id -> FV
tyCoFVsOfCoVar Id
v Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
  = (Id -> FV
unitFV Id
v FV -> FV -> FV
`unionFV` Type -> FV
tyCoFVsOfType (Id -> Type
varType Id
v)) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc

tyCoFVsOfProv :: UnivCoProvenance -> FV
tyCoFVsOfProv :: UnivCoProvenance -> FV
tyCoFVsOfProv UnivCoProvenance
UnsafeCoerceProv    Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = FV
emptyFV Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfProv (PhantomProv Coercion
co)    Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfProv (ProofIrrelProv Coercion
co) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = Coercion -> FV
tyCoFVsOfCo Coercion
co Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfProv (PluginProv String
_)      Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = FV
emptyFV Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc

tyCoFVsOfCos :: [Coercion] -> FV
tyCoFVsOfCos :: [Coercion] -> FV
tyCoFVsOfCos []       Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = FV
emptyFV Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc
tyCoFVsOfCos (Coercion
co:[Coercion]
cos) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc = (Coercion -> FV
tyCoFVsOfCo Coercion
co FV -> FV -> FV
`unionFV` [Coercion] -> FV
tyCoFVsOfCos [Coercion]
cos) Id -> Bool
fv_cand VarSet
in_scope ([Id], VarSet)
acc


------------- Extracting the CoVars of a type or coercion -----------

{-

Note [CoVarsOfX and the InterestingVarFun]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The coVarsOfType, coVarsOfTypes, coVarsOfCo, and coVarsOfCos functions are
implemented in terms of the respective FV equivalents (tyCoFVsOf...), rather
than the VarSet-based flavors (tyCoVarsOf...), despite the performance
considerations outlined in Note [Free variables of types].

This is because FV includes the InterestingVarFun, which is useful here,
because we can cleverly use it to restrict our calculations to CoVars - this
is what getCoVarSet achieves.

See Trac #14880.

-}

getCoVarSet :: FV -> CoVarSet
getCoVarSet :: FV -> VarSet
getCoVarSet FV
fv = ([Id], VarSet) -> VarSet
forall a b. (a, b) -> b
snd (FV
fv Id -> Bool
isCoVar VarSet
emptyVarSet ([], VarSet
emptyVarSet))

coVarsOfType :: Type -> CoVarSet
coVarsOfType :: Type -> VarSet
coVarsOfType Type
ty = FV -> VarSet
getCoVarSet (Type -> FV
tyCoFVsOfType Type
ty)

coVarsOfTypes :: [Type] -> TyCoVarSet
coVarsOfTypes :: [Type] -> VarSet
coVarsOfTypes [Type]
tys = FV -> VarSet
getCoVarSet ([Type] -> FV
tyCoFVsOfTypes [Type]
tys)

coVarsOfCo :: Coercion -> CoVarSet
coVarsOfCo :: Coercion -> VarSet
coVarsOfCo Coercion
co = FV -> VarSet
getCoVarSet (Coercion -> FV
tyCoFVsOfCo Coercion
co)

coVarsOfCos :: [Coercion] -> CoVarSet
coVarsOfCos :: [Coercion] -> VarSet
coVarsOfCos [Coercion]
cos = FV -> VarSet
getCoVarSet ([Coercion] -> FV
tyCoFVsOfCos [Coercion]
cos)

----- Whether a covar is /Almost Devoid/ in a type or coercion ----

-- | Given a covar and a coercion, returns True if covar is almost devoid in
-- the coercion. That is, covar can only appear in Refl and GRefl.
-- See last wrinkle in Note [Unused coercion variable in ForAllCo] in Coercion
almostDevoidCoVarOfCo :: CoVar -> Coercion -> Bool
almostDevoidCoVarOfCo :: Id -> Coercion -> Bool
almostDevoidCoVarOfCo Id
cv Coercion
co =
  Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv

almost_devoid_co_var_of_co :: Coercion -> CoVar -> Bool
almost_devoid_co_var_of_co :: Coercion -> Id -> Bool
almost_devoid_co_var_of_co (Refl {}) Id
_ = Bool
True   -- covar is allowed in Refl and
almost_devoid_co_var_of_co (GRefl {}) Id
_ = Bool
True  -- GRefl, so we don't look into
                                                -- the coercions
almost_devoid_co_var_of_co (TyConAppCo Role
_ TyCon
_ [Coercion]
cos) Id
cv
  = [Coercion] -> Id -> Bool
almost_devoid_co_var_of_cos [Coercion]
cos Id
cv
almost_devoid_co_var_of_co (AppCo Coercion
co Coercion
arg) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
  Bool -> Bool -> Bool
&& Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
arg Id
cv
almost_devoid_co_var_of_co (ForAllCo Id
v Coercion
kind_co Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
kind_co Id
cv
  Bool -> Bool -> Bool
&& (Id
v Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
cv Bool -> Bool -> Bool
|| Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv)
almost_devoid_co_var_of_co (FunCo Role
_ Coercion
co1 Coercion
co2) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co1 Id
cv
  Bool -> Bool -> Bool
&& Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co2 Id
cv
almost_devoid_co_var_of_co (CoVarCo Id
v) Id
cv = Id
v Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
/= Id
cv
almost_devoid_co_var_of_co (HoleCo CoercionHole
h)  Id
cv = (CoercionHole -> Id
coHoleCoVar CoercionHole
h) Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
/= Id
cv
almost_devoid_co_var_of_co (AxiomInstCo CoAxiom Branched
_ Int
_ [Coercion]
cos) Id
cv
  = [Coercion] -> Id -> Bool
almost_devoid_co_var_of_cos [Coercion]
cos Id
cv
almost_devoid_co_var_of_co (UnivCo UnivCoProvenance
p Role
_ Type
t1 Type
t2) Id
cv
  = UnivCoProvenance -> Id -> Bool
almost_devoid_co_var_of_prov UnivCoProvenance
p Id
cv
  Bool -> Bool -> Bool
&& Type -> Id -> Bool
almost_devoid_co_var_of_type Type
t1 Id
cv
  Bool -> Bool -> Bool
&& Type -> Id -> Bool
almost_devoid_co_var_of_type Type
t2 Id
cv
almost_devoid_co_var_of_co (SymCo Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_co (TransCo Coercion
co1 Coercion
co2) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co1 Id
cv
  Bool -> Bool -> Bool
&& Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co2 Id
cv
almost_devoid_co_var_of_co (NthCo Role
_ Int
_ Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_co (LRCo LeftOrRight
_ Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_co (InstCo Coercion
co Coercion
arg) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
  Bool -> Bool -> Bool
&& Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
arg Id
cv
almost_devoid_co_var_of_co (KindCo Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_co (SubCo Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_co (AxiomRuleCo CoAxiomRule
_ [Coercion]
cs) Id
cv
  = [Coercion] -> Id -> Bool
almost_devoid_co_var_of_cos [Coercion]
cs Id
cv

almost_devoid_co_var_of_cos :: [Coercion] -> CoVar -> Bool
almost_devoid_co_var_of_cos :: [Coercion] -> Id -> Bool
almost_devoid_co_var_of_cos [] Id
_ = Bool
True
almost_devoid_co_var_of_cos (Coercion
co:[Coercion]
cos) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
  Bool -> Bool -> Bool
&& [Coercion] -> Id -> Bool
almost_devoid_co_var_of_cos [Coercion]
cos Id
cv

almost_devoid_co_var_of_prov :: UnivCoProvenance -> CoVar -> Bool
almost_devoid_co_var_of_prov :: UnivCoProvenance -> Id -> Bool
almost_devoid_co_var_of_prov (PhantomProv Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_prov (ProofIrrelProv Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_prov UnivCoProvenance
UnsafeCoerceProv Id
_ = Bool
True
almost_devoid_co_var_of_prov (PluginProv String
_) Id
_ = Bool
True

almost_devoid_co_var_of_type :: Type -> CoVar -> Bool
almost_devoid_co_var_of_type :: Type -> Id -> Bool
almost_devoid_co_var_of_type (TyVarTy Id
_) Id
_ = Bool
True
almost_devoid_co_var_of_type (TyConApp TyCon
_ [Type]
tys) Id
cv
  = [Type] -> Id -> Bool
almost_devoid_co_var_of_types [Type]
tys Id
cv
almost_devoid_co_var_of_type (LitTy {}) Id
_ = Bool
True
almost_devoid_co_var_of_type (AppTy Type
fun Type
arg) Id
cv
  = Type -> Id -> Bool
almost_devoid_co_var_of_type Type
fun Id
cv
  Bool -> Bool -> Bool
&& Type -> Id -> Bool
almost_devoid_co_var_of_type Type
arg Id
cv
almost_devoid_co_var_of_type (FunTy Type
arg Type
res) Id
cv
  = Type -> Id -> Bool
almost_devoid_co_var_of_type Type
arg Id
cv
  Bool -> Bool -> Bool
&& Type -> Id -> Bool
almost_devoid_co_var_of_type Type
res Id
cv
almost_devoid_co_var_of_type (ForAllTy (Bndr Id
v ArgFlag
_) Type
ty) Id
cv
  = Type -> Id -> Bool
almost_devoid_co_var_of_type (Id -> Type
varType Id
v) Id
cv
  Bool -> Bool -> Bool
&& (Id
v Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
cv Bool -> Bool -> Bool
|| Type -> Id -> Bool
almost_devoid_co_var_of_type Type
ty Id
cv)
almost_devoid_co_var_of_type (CastTy Type
ty Coercion
co) Id
cv
  = Type -> Id -> Bool
almost_devoid_co_var_of_type Type
ty Id
cv
  Bool -> Bool -> Bool
&& Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv
almost_devoid_co_var_of_type (CoercionTy Coercion
co) Id
cv
  = Coercion -> Id -> Bool
almost_devoid_co_var_of_co Coercion
co Id
cv

almost_devoid_co_var_of_types :: [Type] -> CoVar -> Bool
almost_devoid_co_var_of_types :: [Type] -> Id -> Bool
almost_devoid_co_var_of_types [] Id
_ = Bool
True
almost_devoid_co_var_of_types (Type
ty:[Type]
tys) Id
cv
  = Type -> Id -> Bool
almost_devoid_co_var_of_type Type
ty Id
cv
  Bool -> Bool -> Bool
&& [Type] -> Id -> Bool
almost_devoid_co_var_of_types [Type]
tys Id
cv

------------- Injective free vars -----------------

-- | Returns the free variables of a 'TyConBinder' that are in injective
-- positions. (See @Note [Kind annotations on TyConApps]@ in "TcSplice" for an
-- explanation of what an injective position is.)
injectiveVarsOfBinder :: TyConBinder -> FV
injectiveVarsOfBinder :: TyConBinder -> FV
injectiveVarsOfBinder (Bndr Id
tv TyConBndrVis
vis) =
  case TyConBndrVis
vis of
    TyConBndrVis
AnonTCB           -> Type -> FV
injectiveVarsOfType (Id -> Type
varType Id
tv)
    NamedTCB ArgFlag
Required -> Id -> FV
unitFV Id
tv FV -> FV -> FV
`unionFV`
                         Type -> FV
injectiveVarsOfType (Id -> Type
varType Id
tv)
    NamedTCB ArgFlag
_        -> FV
emptyFV

-- | Returns the free variables of a 'Type' that are in injective positions.
-- (See @Note [Kind annotations on TyConApps]@ in "TcSplice" for an explanation
-- of what an injective position is.)
injectiveVarsOfType :: Type -> FV
injectiveVarsOfType :: Type -> FV
injectiveVarsOfType = Type -> FV
go
  where
    go :: Type -> FV
go Type
ty                | Just Type
ty' <- Type -> Maybe Type
coreView Type
ty
                         = Type -> FV
go Type
ty'
    go (TyVarTy Id
v)       = Id -> FV
unitFV Id
v FV -> FV -> FV
`unionFV` Type -> FV
go (Id -> Type
tyVarKind Id
v)
    go (AppTy Type
f Type
a)       = Type -> FV
go Type
f FV -> FV -> FV
`unionFV` Type -> FV
go Type
a
    go (FunTy Type
ty1 Type
ty2)   = Type -> FV
go Type
ty1 FV -> FV -> FV
`unionFV` Type -> FV
go Type
ty2
    go (TyConApp TyCon
tc [Type]
tys) =
      case TyCon -> Injectivity
tyConInjectivityInfo TyCon
tc of
        Injectivity
NotInjective  -> FV
emptyFV
        Injective [Bool]
inj -> (Type -> FV) -> [Type] -> FV
forall a. (a -> FV) -> [a] -> FV
mapUnionFV Type -> FV
go ([Type] -> FV) -> [Type] -> FV
forall a b. (a -> b) -> a -> b
$
                         [Bool] -> [Type] -> [Type]
forall a. [Bool] -> [a] -> [a]
filterByList ([Bool]
inj [Bool] -> [Bool] -> [Bool]
forall a. [a] -> [a] -> [a]
++ Bool -> [Bool]
forall a. a -> [a]
repeat Bool
True) [Type]
tys
                         -- Oversaturated arguments to a tycon are
                         -- always injective, hence the repeat True
    go (ForAllTy TyCoVarBinder
tvb Type
ty) = TyCoVarBinder -> FV -> FV
tyCoFVsBndr TyCoVarBinder
tvb (FV -> FV) -> FV -> FV
forall a b. (a -> b) -> a -> b
$ Type -> FV
go (TyCoVarBinder -> Type
forall argf. VarBndr Id argf -> Type
binderType TyCoVarBinder
tvb)
                                             FV -> FV -> FV
`unionFV` Type -> FV
go Type
ty
    go LitTy{}           = FV
emptyFV
    go (CastTy Type
ty Coercion
_)     = Type -> FV
go Type
ty
    go CoercionTy{}      = FV
emptyFV

------------- No free vars -----------------

-- | Returns True if this type has no free variables. Should be the same as
-- isEmptyVarSet . tyCoVarsOfType, but faster in the non-forall case.
noFreeVarsOfType :: Type -> Bool
noFreeVarsOfType :: Type -> Bool
noFreeVarsOfType (TyVarTy Id
_)      = Bool
False
noFreeVarsOfType (AppTy Type
t1 Type
t2)    = Type -> Bool
noFreeVarsOfType Type
t1 Bool -> Bool -> Bool
&& Type -> Bool
noFreeVarsOfType Type
t2
noFreeVarsOfType (TyConApp TyCon
_ [Type]
tys) = (Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
noFreeVarsOfType [Type]
tys
noFreeVarsOfType ty :: Type
ty@(ForAllTy {}) = VarSet -> Bool
isEmptyVarSet (Type -> VarSet
tyCoVarsOfType Type
ty)
noFreeVarsOfType (FunTy Type
t1 Type
t2)    = Type -> Bool
noFreeVarsOfType Type
t1 Bool -> Bool -> Bool
&& Type -> Bool
noFreeVarsOfType Type
t2
noFreeVarsOfType (LitTy TyLit
_)        = Bool
True
noFreeVarsOfType (CastTy Type
ty Coercion
co)   = Type -> Bool
noFreeVarsOfType Type
ty Bool -> Bool -> Bool
&& Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfType (CoercionTy Coercion
co)  = Coercion -> Bool
noFreeVarsOfCo Coercion
co

noFreeVarsOfMCo :: MCoercion -> Bool
noFreeVarsOfMCo :: MCoercion -> Bool
noFreeVarsOfMCo MCoercion
MRefl    = Bool
True
noFreeVarsOfMCo (MCo Coercion
co) = Coercion -> Bool
noFreeVarsOfCo Coercion
co

noFreeVarsOfTypes :: [Type] -> Bool
noFreeVarsOfTypes :: [Type] -> Bool
noFreeVarsOfTypes = (Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
noFreeVarsOfType

-- | Returns True if this coercion has no free variables. Should be the same as
-- isEmptyVarSet . tyCoVarsOfCo, but faster in the non-forall case.
noFreeVarsOfCo :: Coercion -> Bool
noFreeVarsOfCo :: Coercion -> Bool
noFreeVarsOfCo (Refl Type
ty)              = Type -> Bool
noFreeVarsOfType Type
ty
noFreeVarsOfCo (GRefl Role
_ Type
ty MCoercion
co)        = Type -> Bool
noFreeVarsOfType Type
ty Bool -> Bool -> Bool
&& MCoercion -> Bool
noFreeVarsOfMCo MCoercion
co
noFreeVarsOfCo (TyConAppCo Role
_ TyCon
_ [Coercion]
args)  = (Coercion -> Bool) -> [Coercion] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Coercion -> Bool
noFreeVarsOfCo [Coercion]
args
noFreeVarsOfCo (AppCo Coercion
c1 Coercion
c2)          = Coercion -> Bool
noFreeVarsOfCo Coercion
c1 Bool -> Bool -> Bool
&& Coercion -> Bool
noFreeVarsOfCo Coercion
c2
noFreeVarsOfCo co :: Coercion
co@(ForAllCo {})       = VarSet -> Bool
isEmptyVarSet (Coercion -> VarSet
tyCoVarsOfCo Coercion
co)
noFreeVarsOfCo (FunCo Role
_ Coercion
c1 Coercion
c2)        = Coercion -> Bool
noFreeVarsOfCo Coercion
c1 Bool -> Bool -> Bool
&& Coercion -> Bool
noFreeVarsOfCo Coercion
c2
noFreeVarsOfCo (CoVarCo Id
_)            = Bool
False
noFreeVarsOfCo (HoleCo {})            = Bool
True    -- I'm unsure; probably never happens
noFreeVarsOfCo (AxiomInstCo CoAxiom Branched
_ Int
_ [Coercion]
args) = (Coercion -> Bool) -> [Coercion] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Coercion -> Bool
noFreeVarsOfCo [Coercion]
args
noFreeVarsOfCo (UnivCo UnivCoProvenance
p Role
_ Type
t1 Type
t2)     = UnivCoProvenance -> Bool
noFreeVarsOfProv UnivCoProvenance
p Bool -> Bool -> Bool
&&
                                        Type -> Bool
noFreeVarsOfType Type
t1 Bool -> Bool -> Bool
&&
                                        Type -> Bool
noFreeVarsOfType Type
t2
noFreeVarsOfCo (SymCo Coercion
co)             = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfCo (TransCo Coercion
co1 Coercion
co2)      = Coercion -> Bool
noFreeVarsOfCo Coercion
co1 Bool -> Bool -> Bool
&& Coercion -> Bool
noFreeVarsOfCo Coercion
co2
noFreeVarsOfCo (NthCo Role
_ Int
_ Coercion
co)         = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfCo (LRCo LeftOrRight
_ Coercion
co)            = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfCo (InstCo Coercion
co1 Coercion
co2)       = Coercion -> Bool
noFreeVarsOfCo Coercion
co1 Bool -> Bool -> Bool
&& Coercion -> Bool
noFreeVarsOfCo Coercion
co2
noFreeVarsOfCo (KindCo Coercion
co)            = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfCo (SubCo Coercion
co)             = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfCo (AxiomRuleCo CoAxiomRule
_ [Coercion]
cs)     = (Coercion -> Bool) -> [Coercion] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Coercion -> Bool
noFreeVarsOfCo [Coercion]
cs

-- | Returns True if this UnivCoProv has no free variables. Should be the same as
-- isEmptyVarSet . tyCoVarsOfProv, but faster in the non-forall case.
noFreeVarsOfProv :: UnivCoProvenance -> Bool
noFreeVarsOfProv :: UnivCoProvenance -> Bool
noFreeVarsOfProv UnivCoProvenance
UnsafeCoerceProv    = Bool
True
noFreeVarsOfProv (PhantomProv Coercion
co)    = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfProv (ProofIrrelProv Coercion
co) = Coercion -> Bool
noFreeVarsOfCo Coercion
co
noFreeVarsOfProv (PluginProv {})     = Bool
True

{-
%************************************************************************
%*                                                                      *
                        Substitutions
      Data type defined here to avoid unnecessary mutual recursion
%*                                                                      *
%************************************************************************
-}

-- | Type & coercion substitution
--
-- #tcvsubst_invariant#
-- The following invariants must hold of a 'TCvSubst':
--
-- 1. The in-scope set is needed /only/ to
-- guide the generation of fresh uniques
--
-- 2. In particular, the /kind/ of the type variables in
-- the in-scope set is not relevant
--
-- 3. The substitution is only applied ONCE! This is because
-- in general such application will not reach a fixed point.
data TCvSubst
  = TCvSubst InScopeSet -- The in-scope type and kind variables
             TvSubstEnv -- Substitutes both type and kind variables
             CvSubstEnv -- Substitutes coercion variables
        -- See Note [Substitutions apply only once]
        -- and Note [Extending the TvSubstEnv]
        -- and Note [Substituting types and coercions]
        -- and Note [The substitution invariant]

-- | A substitution of 'Type's for 'TyVar's
--                 and 'Kind's for 'KindVar's
type TvSubstEnv = TyVarEnv Type
  -- NB: A TvSubstEnv is used
  --   both inside a TCvSubst (with the apply-once invariant
  --        discussed in Note [Substitutions apply only once],
  --   and  also independently in the middle of matching,
  --        and unification (see Types.Unify).
  -- So you have to look at the context to know if it's idempotent or
  -- apply-once or whatever

-- | A substitution of 'Coercion's for 'CoVar's
type CvSubstEnv = CoVarEnv Coercion

{- Note [The substitution invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When calling (substTy subst ty) it should be the case that
the in-scope set in the substitution is a superset of both:

  (SIa) The free vars of the range of the substitution
  (SIb) The free vars of ty minus the domain of the substitution

The same rules apply to other substitutions (notably CoreSubst.Subst)

* Reason for (SIa). Consider
      substTy [a :-> Maybe b] (forall b. b->a)
  we must rename the forall b, to get
      forall b2. b2 -> Maybe b
  Making 'b' part of the in-scope set forces this renaming to
  take place.

* Reason for (SIb). Consider
     substTy [a :-> Maybe b] (forall b. (a,b,x))
  Then if we use the in-scope set {b}, satisfying (SIa), there is
  a danger we will rename the forall'd variable to 'x' by mistake,
  getting this:
      forall x. (Maybe b, x, x)
  Breaking (SIb) caused the bug from #11371.

Note: if the free vars of the range of the substitution are freshly created,
then the problems of (SIa) can't happen, and so it would be sound to
ignore (SIa).

Note [Substitutions apply only once]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We use TCvSubsts to instantiate things, and we might instantiate
        forall a b. ty
with the types
        [a, b], or [b, a].
So the substitution might go [a->b, b->a].  A similar situation arises in Core
when we find a beta redex like
        (/\ a /\ b -> e) b a
Then we also end up with a substitution that permutes type variables. Other
variations happen to; for example [a -> (a, b)].

        ********************************************************
        *** So a substitution must be applied precisely once ***
        ********************************************************

A TCvSubst is not idempotent, but, unlike the non-idempotent substitution
we use during unifications, it must not be repeatedly applied.

Note [Extending the TvSubstEnv]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See #tcvsubst_invariant# for the invariants that must hold.

This invariant allows a short-cut when the subst envs are empty:
if the TvSubstEnv and CvSubstEnv are empty --- i.e. (isEmptyTCvSubst subst)
holds --- then (substTy subst ty) does nothing.

For example, consider:
        (/\a. /\b:(a~Int). ...b..) Int
We substitute Int for 'a'.  The Unique of 'b' does not change, but
nevertheless we add 'b' to the TvSubstEnv, because b's kind does change

This invariant has several crucial consequences:

* In substVarBndr, we need extend the TvSubstEnv
        - if the unique has changed
        - or if the kind has changed

* In substTyVar, we do not need to consult the in-scope set;
  the TvSubstEnv is enough

* In substTy, substTheta, we can short-circuit when the TvSubstEnv is empty

Note [Substituting types and coercions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Types and coercions are mutually recursive, and either may have variables
"belonging" to the other. Thus, every time we wish to substitute in a
type, we may also need to substitute in a coercion, and vice versa.
However, the constructor used to create type variables is distinct from
that of coercion variables, so we carry two VarEnvs in a TCvSubst. Note
that it would be possible to use the CoercionTy constructor to combine
these environments, but that seems like a false economy.

Note that the TvSubstEnv should *never* map a CoVar (built with the Id
constructor) and the CvSubstEnv should *never* map a TyVar. Furthermore,
the range of the TvSubstEnv should *never* include a type headed with
CoercionTy.
-}

emptyTvSubstEnv :: TvSubstEnv
emptyTvSubstEnv :: TyVarEnv Type
emptyTvSubstEnv = TyVarEnv Type
forall a. VarEnv a
emptyVarEnv

emptyCvSubstEnv :: CvSubstEnv
emptyCvSubstEnv :: CoVarEnv Coercion
emptyCvSubstEnv = CoVarEnv Coercion
forall a. VarEnv a
emptyVarEnv

composeTCvSubstEnv :: InScopeSet
                   -> (TvSubstEnv, CvSubstEnv)
                   -> (TvSubstEnv, CvSubstEnv)
                   -> (TvSubstEnv, CvSubstEnv)
-- ^ @(compose env1 env2)(x)@ is @env1(env2(x))@; i.e. apply @env2@ then @env1@.
-- It assumes that both are idempotent.
-- Typically, @env1@ is the refinement to a base substitution @env2@
composeTCvSubstEnv :: InScopeSet
-> (TyVarEnv Type, CoVarEnv Coercion)
-> (TyVarEnv Type, CoVarEnv Coercion)
-> (TyVarEnv Type, CoVarEnv Coercion)
composeTCvSubstEnv InScopeSet
in_scope (TyVarEnv Type
tenv1, CoVarEnv Coercion
cenv1) (TyVarEnv Type
tenv2, CoVarEnv Coercion
cenv2)
  = ( TyVarEnv Type
tenv1 TyVarEnv Type -> TyVarEnv Type -> TyVarEnv Type
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` (Type -> Type) -> TyVarEnv Type -> TyVarEnv Type
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst1) TyVarEnv Type
tenv2
    , CoVarEnv Coercion
cenv1 CoVarEnv Coercion -> CoVarEnv Coercion -> CoVarEnv Coercion
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv` (Coercion -> Coercion) -> CoVarEnv Coercion -> CoVarEnv Coercion
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst1) CoVarEnv Coercion
cenv2 )
        -- First apply env1 to the range of env2
        -- Then combine the two, making sure that env1 loses if
        -- both bind the same variable; that's why env1 is the
        --  *left* argument to plusVarEnv, because the right arg wins
  where
    subst1 :: TCvSubst
subst1 = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv1 CoVarEnv Coercion
cenv1

-- | Composes two substitutions, applying the second one provided first,
-- like in function composition.
composeTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
composeTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
composeTCvSubst (TCvSubst InScopeSet
is1 TyVarEnv Type
tenv1 CoVarEnv Coercion
cenv1) (TCvSubst InScopeSet
is2 TyVarEnv Type
tenv2 CoVarEnv Coercion
cenv2)
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
is3 TyVarEnv Type
tenv3 CoVarEnv Coercion
cenv3
  where
    is3 :: InScopeSet
is3 = InScopeSet
is1 InScopeSet -> InScopeSet -> InScopeSet
`unionInScope` InScopeSet
is2
    (TyVarEnv Type
tenv3, CoVarEnv Coercion
cenv3) = InScopeSet
-> (TyVarEnv Type, CoVarEnv Coercion)
-> (TyVarEnv Type, CoVarEnv Coercion)
-> (TyVarEnv Type, CoVarEnv Coercion)
composeTCvSubstEnv InScopeSet
is3 (TyVarEnv Type
tenv1, CoVarEnv Coercion
cenv1) (TyVarEnv Type
tenv2, CoVarEnv Coercion
cenv2)

emptyTCvSubst :: TCvSubst
emptyTCvSubst :: TCvSubst
emptyTCvSubst = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
emptyInScopeSet TyVarEnv Type
emptyTvSubstEnv CoVarEnv Coercion
emptyCvSubstEnv

mkEmptyTCvSubst :: InScopeSet -> TCvSubst
mkEmptyTCvSubst :: InScopeSet -> TCvSubst
mkEmptyTCvSubst InScopeSet
is = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
is TyVarEnv Type
emptyTvSubstEnv CoVarEnv Coercion
emptyCvSubstEnv

isEmptyTCvSubst :: TCvSubst -> Bool
         -- See Note [Extending the TvSubstEnv]
isEmptyTCvSubst :: TCvSubst -> Bool
isEmptyTCvSubst (TCvSubst InScopeSet
_ TyVarEnv Type
tenv CoVarEnv Coercion
cenv) = TyVarEnv Type -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv TyVarEnv Type
tenv Bool -> Bool -> Bool
&& CoVarEnv Coercion -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv CoVarEnv Coercion
cenv

mkTCvSubst :: InScopeSet -> (TvSubstEnv, CvSubstEnv) -> TCvSubst
mkTCvSubst :: InScopeSet -> (TyVarEnv Type, CoVarEnv Coercion) -> TCvSubst
mkTCvSubst InScopeSet
in_scope (TyVarEnv Type
tenv, CoVarEnv Coercion
cenv) = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv

mkTvSubst :: InScopeSet -> TvSubstEnv -> TCvSubst
-- ^ Make a TCvSubst with specified tyvar subst and empty covar subst
mkTvSubst :: InScopeSet -> TyVarEnv Type -> TCvSubst
mkTvSubst InScopeSet
in_scope TyVarEnv Type
tenv = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
emptyCvSubstEnv

mkCvSubst :: InScopeSet -> CvSubstEnv -> TCvSubst
-- ^ Make a TCvSubst with specified covar subst and empty tyvar subst
mkCvSubst :: InScopeSet -> CoVarEnv Coercion -> TCvSubst
mkCvSubst InScopeSet
in_scope CoVarEnv Coercion
cenv = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
emptyTvSubstEnv CoVarEnv Coercion
cenv

getTvSubstEnv :: TCvSubst -> TvSubstEnv
getTvSubstEnv :: TCvSubst -> TyVarEnv Type
getTvSubstEnv (TCvSubst InScopeSet
_ TyVarEnv Type
env CoVarEnv Coercion
_) = TyVarEnv Type
env

getCvSubstEnv :: TCvSubst -> CvSubstEnv
getCvSubstEnv :: TCvSubst -> CoVarEnv Coercion
getCvSubstEnv (TCvSubst InScopeSet
_ TyVarEnv Type
_ CoVarEnv Coercion
env) = CoVarEnv Coercion
env

getTCvInScope :: TCvSubst -> InScopeSet
getTCvInScope :: TCvSubst -> InScopeSet
getTCvInScope (TCvSubst InScopeSet
in_scope TyVarEnv Type
_ CoVarEnv Coercion
_) = InScopeSet
in_scope

-- | Returns the free variables of the types in the range of a substitution as
-- a non-deterministic set.
getTCvSubstRangeFVs :: TCvSubst -> VarSet
getTCvSubstRangeFVs :: TCvSubst -> VarSet
getTCvSubstRangeFVs (TCvSubst InScopeSet
_ TyVarEnv Type
tenv CoVarEnv Coercion
cenv)
    = VarSet -> VarSet -> VarSet
unionVarSet VarSet
tenvFVs VarSet
cenvFVs
  where
    tenvFVs :: VarSet
tenvFVs = TyVarEnv Type -> VarSet
tyCoVarsOfTypesSet TyVarEnv Type
tenv
    cenvFVs :: VarSet
cenvFVs = CoVarEnv Coercion -> VarSet
tyCoVarsOfCosSet CoVarEnv Coercion
cenv

isInScope :: Var -> TCvSubst -> Bool
isInScope :: Id -> TCvSubst -> Bool
isInScope Id
v (TCvSubst InScopeSet
in_scope TyVarEnv Type
_ CoVarEnv Coercion
_) = Id
v Id -> InScopeSet -> Bool
`elemInScopeSet` InScopeSet
in_scope

notElemTCvSubst :: Var -> TCvSubst -> Bool
notElemTCvSubst :: Id -> TCvSubst -> Bool
notElemTCvSubst Id
v (TCvSubst InScopeSet
_ TyVarEnv Type
tenv CoVarEnv Coercion
cenv)
  | Id -> Bool
isTyVar Id
v
  = Bool -> Bool
not (Id
v Id -> TyVarEnv Type -> Bool
forall a. Id -> VarEnv a -> Bool
`elemVarEnv` TyVarEnv Type
tenv)
  | Bool
otherwise
  = Bool -> Bool
not (Id
v Id -> CoVarEnv Coercion -> Bool
forall a. Id -> VarEnv a -> Bool
`elemVarEnv` CoVarEnv Coercion
cenv)

setTvSubstEnv :: TCvSubst -> TvSubstEnv -> TCvSubst
setTvSubstEnv :: TCvSubst -> TyVarEnv Type -> TCvSubst
setTvSubstEnv (TCvSubst InScopeSet
in_scope TyVarEnv Type
_ CoVarEnv Coercion
cenv) TyVarEnv Type
tenv = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv

setCvSubstEnv :: TCvSubst -> CvSubstEnv -> TCvSubst
setCvSubstEnv :: TCvSubst -> CoVarEnv Coercion -> TCvSubst
setCvSubstEnv (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
_) CoVarEnv Coercion
cenv = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv

zapTCvSubst :: TCvSubst -> TCvSubst
zapTCvSubst :: TCvSubst -> TCvSubst
zapTCvSubst (TCvSubst InScopeSet
in_scope TyVarEnv Type
_ CoVarEnv Coercion
_) = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
forall a. VarEnv a
emptyVarEnv CoVarEnv Coercion
forall a. VarEnv a
emptyVarEnv

extendTCvInScope :: TCvSubst -> Var -> TCvSubst
extendTCvInScope :: TCvSubst -> Id -> TCvSubst
extendTCvInScope (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
var
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet -> Id -> InScopeSet
extendInScopeSet InScopeSet
in_scope Id
var) TyVarEnv Type
tenv CoVarEnv Coercion
cenv

extendTCvInScopeList :: TCvSubst -> [Var] -> TCvSubst
extendTCvInScopeList :: TCvSubst -> [Id] -> TCvSubst
extendTCvInScopeList (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) [Id]
vars
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet -> [Id] -> InScopeSet
extendInScopeSetList InScopeSet
in_scope [Id]
vars) TyVarEnv Type
tenv CoVarEnv Coercion
cenv

extendTCvInScopeSet :: TCvSubst -> VarSet -> TCvSubst
extendTCvInScopeSet :: TCvSubst -> VarSet -> TCvSubst
extendTCvInScopeSet (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) VarSet
vars
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
vars) TyVarEnv Type
tenv CoVarEnv Coercion
cenv

extendTCvSubst :: TCvSubst -> TyCoVar -> Type -> TCvSubst
extendTCvSubst :: TCvSubst -> Id -> Type -> TCvSubst
extendTCvSubst TCvSubst
subst Id
v Type
ty
  | Id -> Bool
isTyVar Id
v
  = TCvSubst -> Id -> Type -> TCvSubst
extendTvSubst TCvSubst
subst Id
v Type
ty
  | CoercionTy Coercion
co <- Type
ty
  = TCvSubst -> Id -> Coercion -> TCvSubst
extendCvSubst TCvSubst
subst Id
v Coercion
co
  | Bool
otherwise
  = String -> SDoc -> TCvSubst
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"extendTCvSubst" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
v SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"|->" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)

extendTCvSubstWithClone :: TCvSubst -> TyCoVar -> TyCoVar -> TCvSubst
extendTCvSubstWithClone :: TCvSubst -> Id -> Id -> TCvSubst
extendTCvSubstWithClone TCvSubst
subst Id
tcv
  | Id -> Bool
isTyVar Id
tcv = TCvSubst -> Id -> Id -> TCvSubst
extendTvSubstWithClone TCvSubst
subst Id
tcv
  | Bool
otherwise   = TCvSubst -> Id -> Id -> TCvSubst
extendCvSubstWithClone TCvSubst
subst Id
tcv

extendTvSubst :: TCvSubst -> TyVar -> Type -> TCvSubst
extendTvSubst :: TCvSubst -> Id -> Type -> TCvSubst
extendTvSubst (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
tv Type
ty
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope (TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tenv Id
tv Type
ty) CoVarEnv Coercion
cenv

extendTvSubstBinderAndInScope :: TCvSubst -> TyCoBinder -> Type -> TCvSubst
extendTvSubstBinderAndInScope :: TCvSubst -> TyCoBinder -> Type -> TCvSubst
extendTvSubstBinderAndInScope TCvSubst
subst (Named (Bndr Id
v ArgFlag
_)) Type
ty
  = ASSERT( isTyVar v )
    TCvSubst -> Id -> Type -> TCvSubst
extendTvSubstAndInScope TCvSubst
subst Id
v Type
ty
extendTvSubstBinderAndInScope TCvSubst
subst (Anon Type
_)     Type
_
  = TCvSubst
subst

extendTvSubstWithClone :: TCvSubst -> TyVar -> TyVar -> TCvSubst
-- Adds a new tv -> tv mapping, /and/ extends the in-scope set
extendTvSubstWithClone :: TCvSubst -> Id -> Id -> TCvSubst
extendTvSubstWithClone (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
tv Id
tv'
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
new_in_scope)
             (TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tenv Id
tv (Id -> Type
mkTyVarTy Id
tv'))
             CoVarEnv Coercion
cenv
  where
    new_in_scope :: VarSet
new_in_scope = Type -> VarSet
tyCoVarsOfType (Id -> Type
tyVarKind Id
tv') VarSet -> Id -> VarSet
`extendVarSet` Id
tv'

extendCvSubst :: TCvSubst -> CoVar -> Coercion -> TCvSubst
extendCvSubst :: TCvSubst -> Id -> Coercion -> TCvSubst
extendCvSubst (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
v Coercion
co
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv (CoVarEnv Coercion -> Id -> Coercion -> CoVarEnv Coercion
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv CoVarEnv Coercion
cenv Id
v Coercion
co)

extendCvSubstWithClone :: TCvSubst -> CoVar -> CoVar -> TCvSubst
extendCvSubstWithClone :: TCvSubst -> Id -> Id -> TCvSubst
extendCvSubstWithClone (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
cv Id
cv'
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet -> VarSet -> InScopeSet
extendInScopeSetSet InScopeSet
in_scope VarSet
new_in_scope)
             TyVarEnv Type
tenv
             (CoVarEnv Coercion -> Id -> Coercion -> CoVarEnv Coercion
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv CoVarEnv Coercion
cenv Id
cv (Id -> Coercion
mkCoVarCo Id
cv'))
  where
    new_in_scope :: VarSet
new_in_scope = Type -> VarSet
tyCoVarsOfType (Id -> Type
varType Id
cv') VarSet -> Id -> VarSet
`extendVarSet` Id
cv'

extendTvSubstAndInScope :: TCvSubst -> TyVar -> Type -> TCvSubst
-- Also extends the in-scope set
extendTvSubstAndInScope :: TCvSubst -> Id -> Type -> TCvSubst
extendTvSubstAndInScope (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
tv Type
ty
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> VarSet -> InScopeSet
`extendInScopeSetSet` Type -> VarSet
tyCoVarsOfType Type
ty)
             (TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tenv Id
tv Type
ty)
             CoVarEnv Coercion
cenv

extendTvSubstList :: TCvSubst -> [Var] -> [Type] -> TCvSubst
extendTvSubstList :: TCvSubst -> [Id] -> [Type] -> TCvSubst
extendTvSubstList TCvSubst
subst [Id]
tvs [Type]
tys
  = (TCvSubst -> Id -> Type -> TCvSubst)
-> TCvSubst -> [Id] -> [Type] -> TCvSubst
forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 TCvSubst -> Id -> Type -> TCvSubst
extendTvSubst TCvSubst
subst [Id]
tvs [Type]
tys

extendTCvSubstList :: TCvSubst -> [Var] -> [Type] -> TCvSubst
extendTCvSubstList :: TCvSubst -> [Id] -> [Type] -> TCvSubst
extendTCvSubstList TCvSubst
subst [Id]
tvs [Type]
tys
  = (TCvSubst -> Id -> Type -> TCvSubst)
-> TCvSubst -> [Id] -> [Type] -> TCvSubst
forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 TCvSubst -> Id -> Type -> TCvSubst
extendTCvSubst TCvSubst
subst [Id]
tvs [Type]
tys

unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
-- Works when the ranges are disjoint
unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst
unionTCvSubst (TCvSubst InScopeSet
in_scope1 TyVarEnv Type
tenv1 CoVarEnv Coercion
cenv1) (TCvSubst InScopeSet
in_scope2 TyVarEnv Type
tenv2 CoVarEnv Coercion
cenv2)
  = ASSERT( not (tenv1 `intersectsVarEnv` tenv2)
         && not (cenv1 `intersectsVarEnv` cenv2) )
    InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet
in_scope1 InScopeSet -> InScopeSet -> InScopeSet
`unionInScope` InScopeSet
in_scope2)
             (TyVarEnv Type
tenv1     TyVarEnv Type -> TyVarEnv Type -> TyVarEnv Type
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv`   TyVarEnv Type
tenv2)
             (CoVarEnv Coercion
cenv1     CoVarEnv Coercion -> CoVarEnv Coercion -> CoVarEnv Coercion
forall a. VarEnv a -> VarEnv a -> VarEnv a
`plusVarEnv`   CoVarEnv Coercion
cenv2)

-- mkTvSubstPrs and zipTvSubst generate the in-scope set from
-- the types given; but it's just a thunk so with a bit of luck
-- it'll never be evaluated

-- | Generates the in-scope set for the 'TCvSubst' from the types in the incoming
-- environment. No CoVars, please!
zipTvSubst :: HasDebugCallStack => [TyVar] -> [Type] -> TCvSubst
zipTvSubst :: [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
tvs [Type]
tys
  = InScopeSet -> TyVarEnv Type -> TCvSubst
mkTvSubst (VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
tyCoVarsOfTypes [Type]
tys)) TyVarEnv Type
tenv
  where
    tenv :: TyVarEnv Type
tenv = [Id] -> [Type] -> TyVarEnv Type
HasDebugCallStack => [Id] -> [Type] -> TyVarEnv Type
zipTyEnv [Id]
tvs [Type]
tys

-- | Generates the in-scope set for the 'TCvSubst' from the types in the incoming
-- environment.  No TyVars, please!
zipCvSubst :: HasDebugCallStack => [CoVar] -> [Coercion] -> TCvSubst
zipCvSubst :: [Id] -> [Coercion] -> TCvSubst
zipCvSubst [Id]
cvs [Coercion]
cos
  = InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (VarSet -> InScopeSet
mkInScopeSet ([Coercion] -> VarSet
tyCoVarsOfCos [Coercion]
cos)) TyVarEnv Type
emptyTvSubstEnv CoVarEnv Coercion
cenv
  where
    cenv :: CoVarEnv Coercion
cenv = [Id] -> [Coercion] -> CoVarEnv Coercion
HasDebugCallStack => [Id] -> [Coercion] -> CoVarEnv Coercion
zipCoEnv [Id]
cvs [Coercion]
cos

zipTCvSubst :: HasDebugCallStack => [TyCoVar] -> [Type] -> TCvSubst
zipTCvSubst :: [Id] -> [Type] -> TCvSubst
zipTCvSubst [Id]
tcvs [Type]
tys
  = [Id] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst [Id]
tcvs [Type]
tys (InScopeSet -> TCvSubst
mkEmptyTCvSubst (InScopeSet -> TCvSubst) -> InScopeSet -> TCvSubst
forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
tyCoVarsOfTypes [Type]
tys))
  where zip_tcvsubst :: [TyCoVar] -> [Type] -> TCvSubst -> TCvSubst
        zip_tcvsubst :: [Id] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst (Id
tv:[Id]
tvs) (Type
ty:[Type]
tys) TCvSubst
subst
          = [Id] -> [Type] -> TCvSubst -> TCvSubst
zip_tcvsubst [Id]
tvs [Type]
tys (TCvSubst -> Id -> Type -> TCvSubst
extendTCvSubst TCvSubst
subst Id
tv Type
ty)
        zip_tcvsubst [] [] TCvSubst
subst = TCvSubst
subst -- empty case
        zip_tcvsubst [Id]
_  [Type]
_  TCvSubst
_     = String -> SDoc -> TCvSubst
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipTCvSubst: length mismatch"
                                            ([Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
tcvs SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys)

-- | Generates the in-scope set for the 'TCvSubst' from the types in the
-- incoming environment. No CoVars, please!
mkTvSubstPrs :: [(TyVar, Type)] -> TCvSubst
mkTvSubstPrs :: [(Id, Type)] -> TCvSubst
mkTvSubstPrs [(Id, Type)]
prs =
    ASSERT2( onlyTyVarsAndNoCoercionTy, text "prs" <+> ppr prs )
    InScopeSet -> TyVarEnv Type -> TCvSubst
mkTvSubst InScopeSet
in_scope TyVarEnv Type
tenv
  where tenv :: TyVarEnv Type
tenv = [(Id, Type)] -> TyVarEnv Type
forall a. [(Id, a)] -> VarEnv a
mkVarEnv [(Id, Type)]
prs
        in_scope :: InScopeSet
in_scope = VarSet -> InScopeSet
mkInScopeSet (VarSet -> InScopeSet) -> VarSet -> InScopeSet
forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
tyCoVarsOfTypes ([Type] -> VarSet) -> [Type] -> VarSet
forall a b. (a -> b) -> a -> b
$ ((Id, Type) -> Type) -> [(Id, Type)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Id, Type) -> Type
forall a b. (a, b) -> b
snd [(Id, Type)]
prs
        onlyTyVarsAndNoCoercionTy :: Bool
onlyTyVarsAndNoCoercionTy =
          [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Id -> Bool
isTyVar Id
tv Bool -> Bool -> Bool
&& Bool -> Bool
not (Type -> Bool
isCoercionTy Type
ty)
              | (Id
tv, Type
ty) <- [(Id, Type)]
prs ]

zipTyEnv :: HasDebugCallStack => [TyVar] -> [Type] -> TvSubstEnv
zipTyEnv :: [Id] -> [Type] -> TyVarEnv Type
zipTyEnv [Id]
tyvars [Type]
tys
  | Bool
debugIsOn
  , Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
isTyVar [Id]
tyvars)
  = String -> SDoc -> TyVarEnv Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipTyEnv" ([Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
tyvars SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys)
  | Bool
otherwise
  = ASSERT( all (not . isCoercionTy) tys )
    [(Id, Type)] -> TyVarEnv Type
forall a. [(Id, a)] -> VarEnv a
mkVarEnv (String -> [Id] -> [Type] -> [(Id, Type)]
forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual String
"zipTyEnv" [Id]
tyvars [Type]
tys)
        -- There used to be a special case for when
        --      ty == TyVarTy tv
        -- (a not-uncommon case) in which case the substitution was dropped.
        -- But the type-tidier changes the print-name of a type variable without
        -- changing the unique, and that led to a bug.   Why?  Pre-tidying, we had
        -- a type {Foo t}, where Foo is a one-method class.  So Foo is really a newtype.
        -- And it happened that t was the type variable of the class.  Post-tiding,
        -- it got turned into {Foo t2}.  The ext-core printer expanded this using
        -- sourceTypeRep, but that said "Oh, t == t2" because they have the same unique,
        -- and so generated a rep type mentioning t not t2.
        --
        -- Simplest fix is to nuke the "optimisation"

zipCoEnv :: HasDebugCallStack => [CoVar] -> [Coercion] -> CvSubstEnv
zipCoEnv :: [Id] -> [Coercion] -> CoVarEnv Coercion
zipCoEnv [Id]
cvs [Coercion]
cos
  | Bool
debugIsOn
  , Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
isCoVar [Id]
cvs)
  = String -> SDoc -> CoVarEnv Coercion
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"zipCoEnv" ([Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
cvs SDoc -> SDoc -> SDoc
<+> [Coercion] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Coercion]
cos)
  | Bool
otherwise
  = [(Id, Coercion)] -> CoVarEnv Coercion
forall a. [(Id, a)] -> VarEnv a
mkVarEnv (String -> [Id] -> [Coercion] -> [(Id, Coercion)]
forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual String
"zipCoEnv" [Id]
cvs [Coercion]
cos)

instance Outputable TCvSubst where
  ppr :: TCvSubst -> SDoc
ppr (TCvSubst InScopeSet
ins TyVarEnv Type
tenv CoVarEnv Coercion
cenv)
    = SDoc -> SDoc
brackets (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
sep[ String -> SDoc
text String
"TCvSubst",
                      Int -> SDoc -> SDoc
nest Int
2 (String -> SDoc
text String
"In scope:" SDoc -> SDoc -> SDoc
<+> InScopeSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr InScopeSet
ins),
                      Int -> SDoc -> SDoc
nest Int
2 (String -> SDoc
text String
"Type env:" SDoc -> SDoc -> SDoc
<+> TyVarEnv Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyVarEnv Type
tenv),
                      Int -> SDoc -> SDoc
nest Int
2 (String -> SDoc
text String
"Co env:" SDoc -> SDoc -> SDoc
<+> CoVarEnv Coercion -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoVarEnv Coercion
cenv) ]

{-
%************************************************************************
%*                                                                      *
                Performing type or kind substitutions
%*                                                                      *
%************************************************************************

Note [Sym and ForAllCo]
~~~~~~~~~~~~~~~~~~~~~~~
In OptCoercion, we try to push "sym" out to the leaves of a coercion. But,
how do we push sym into a ForAllCo? It's a little ugly.

Here is the typing rule:

h : k1 ~# k2
(tv : k1) |- g : ty1 ~# ty2
----------------------------
ForAllCo tv h g : (ForAllTy (tv : k1) ty1) ~#
                  (ForAllTy (tv : k2) (ty2[tv |-> tv |> sym h]))

Here is what we want:

ForAllCo tv h' g' : (ForAllTy (tv : k2) (ty2[tv |-> tv |> sym h])) ~#
                    (ForAllTy (tv : k1) ty1)


Because the kinds of the type variables to the right of the colon are the kinds
coerced by h', we know (h' : k2 ~# k1). Thus, (h' = sym h).

Now, we can rewrite ty1 to be (ty1[tv |-> tv |> sym h' |> h']). We thus want

ForAllCo tv h' g' :
  (ForAllTy (tv : k2) (ty2[tv |-> tv |> h'])) ~#
  (ForAllTy (tv : k1) (ty1[tv |-> tv |> h'][tv |-> tv |> sym h']))

We thus see that we want

g' : ty2[tv |-> tv |> h'] ~# ty1[tv |-> tv |> h']

and thus g' = sym (g[tv |-> tv |> h']).

Putting it all together, we get this:

sym (ForAllCo tv h g)
==>
ForAllCo tv (sym h) (sym g[tv |-> tv |> sym h])

Note [Substituting in a coercion hole]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It seems highly suspicious to be substituting in a coercion that still
has coercion holes. Yet, this can happen in a situation like this:

  f :: forall k. k :~: Type -> ()
  f Refl = let x :: forall (a :: k). [a] -> ...
               x = ...

When we check x's type signature, we require that k ~ Type. We indeed
know this due to the Refl pattern match, but the eager unifier can't
make use of givens. So, when we're done looking at x's type, a coercion
hole will remain. Then, when we're checking x's definition, we skolemise
x's type (in order to, e.g., bring the scoped type variable `a` into scope).
This requires performing a substitution for the fresh skolem variables.

This subsitution needs to affect the kind of the coercion hole, too --
otherwise, the kind will have an out-of-scope variable in it. More problematically
in practice (we won't actually notice the out-of-scope variable ever), skolems
in the kind might have too high a level, triggering a failure to uphold the
invariant that no free variables in a type have a higher level than the
ambient level in the type checker. In the event of having free variables in the
hole's kind, I'm pretty sure we'll always have an erroneous program, so we
don't need to worry what will happen when the hole gets filled in. After all,
a hole relating a locally-bound type variable will be unable to be solved. This
is why it's OK not to look through the IORef of a coercion hole during
substitution.

-}

-- | Type substitution, see 'zipTvSubst'
substTyWith :: HasCallStack => [TyVar] -> [Type] -> Type -> Type
-- Works only if the domain of the substitution is a
-- superset of the type being substituted into
substTyWith :: [Id] -> [Type] -> Type -> Type
substTyWith [Id]
tvs [Type]
tys = {-#SCC "substTyWith" #-}
                      ASSERT( tvs `equalLength` tys )
                      HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy ([Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
tvs [Type]
tys)

-- | Type substitution, see 'zipTvSubst'. Disables sanity checks.
-- The problems that the sanity checks in substTy catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substTyUnchecked to
-- substTy and remove this function. Please don't use in new code.
substTyWithUnchecked :: [TyVar] -> [Type] -> Type -> Type
substTyWithUnchecked :: [Id] -> [Type] -> Type -> Type
substTyWithUnchecked [Id]
tvs [Type]
tys
  = ASSERT( tvs `equalLength` tys )
    TCvSubst -> Type -> Type
substTyUnchecked ([Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
tvs [Type]
tys)

-- | Substitute tyvars within a type using a known 'InScopeSet'.
-- Pre-condition: the 'in_scope' set should satisfy Note [The substitution
-- invariant]; specifically it should include the free vars of 'tys',
-- and of 'ty' minus the domain of the subst.
substTyWithInScope :: InScopeSet -> [TyVar] -> [Type] -> Type -> Type
substTyWithInScope :: InScopeSet -> [Id] -> [Type] -> Type -> Type
substTyWithInScope InScopeSet
in_scope [Id]
tvs [Type]
tys Type
ty =
  ASSERT( tvs `equalLength` tys )
  HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy (InScopeSet -> TyVarEnv Type -> TCvSubst
mkTvSubst InScopeSet
in_scope TyVarEnv Type
tenv) Type
ty
  where tenv :: TyVarEnv Type
tenv = [Id] -> [Type] -> TyVarEnv Type
HasDebugCallStack => [Id] -> [Type] -> TyVarEnv Type
zipTyEnv [Id]
tvs [Type]
tys

-- | Coercion substitution, see 'zipTvSubst'
substCoWith :: HasCallStack => [TyVar] -> [Type] -> Coercion -> Coercion
substCoWith :: [Id] -> [Type] -> Coercion -> Coercion
substCoWith [Id]
tvs [Type]
tys = ASSERT( tvs `equalLength` tys )
                      HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo ([Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
tvs [Type]
tys)

-- | Coercion substitution, see 'zipTvSubst'. Disables sanity checks.
-- The problems that the sanity checks in substCo catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substCoUnchecked to
-- substCo and remove this function. Please don't use in new code.
substCoWithUnchecked :: [TyVar] -> [Type] -> Coercion -> Coercion
substCoWithUnchecked :: [Id] -> [Type] -> Coercion -> Coercion
substCoWithUnchecked [Id]
tvs [Type]
tys
  = ASSERT( tvs `equalLength` tys )
    TCvSubst -> Coercion -> Coercion
substCoUnchecked ([Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
tvs [Type]
tys)



-- | Substitute covars within a type
substTyWithCoVars :: [CoVar] -> [Coercion] -> Type -> Type
substTyWithCoVars :: [Id] -> [Coercion] -> Type -> Type
substTyWithCoVars [Id]
cvs [Coercion]
cos = HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy ([Id] -> [Coercion] -> TCvSubst
HasDebugCallStack => [Id] -> [Coercion] -> TCvSubst
zipCvSubst [Id]
cvs [Coercion]
cos)

-- | Type substitution, see 'zipTvSubst'
substTysWith :: [TyVar] -> [Type] -> [Type] -> [Type]
substTysWith :: [Id] -> [Type] -> [Type] -> [Type]
substTysWith [Id]
tvs [Type]
tys = ASSERT( tvs `equalLength` tys )
                       HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys ([Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
tvs [Type]
tys)

-- | Type substitution, see 'zipTvSubst'
substTysWithCoVars :: [CoVar] -> [Coercion] -> [Type] -> [Type]
substTysWithCoVars :: [Id] -> [Coercion] -> [Type] -> [Type]
substTysWithCoVars [Id]
cvs [Coercion]
cos = ASSERT( cvs `equalLength` cos )
                             HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys ([Id] -> [Coercion] -> TCvSubst
HasDebugCallStack => [Id] -> [Coercion] -> TCvSubst
zipCvSubst [Id]
cvs [Coercion]
cos)

-- | Substitute within a 'Type' after adding the free variables of the type
-- to the in-scope set. This is useful for the case when the free variables
-- aren't already in the in-scope set or easily available.
-- See also Note [The substitution invariant].
substTyAddInScope :: TCvSubst -> Type -> Type
substTyAddInScope :: TCvSubst -> Type -> Type
substTyAddInScope TCvSubst
subst Type
ty =
  HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy (TCvSubst -> VarSet -> TCvSubst
extendTCvInScopeSet TCvSubst
subst (VarSet -> TCvSubst) -> VarSet -> TCvSubst
forall a b. (a -> b) -> a -> b
$ Type -> VarSet
tyCoVarsOfType Type
ty) Type
ty

-- | When calling `substTy` it should be the case that the in-scope set in
-- the substitution is a superset of the free vars of the range of the
-- substitution.
-- See also Note [The substitution invariant].
isValidTCvSubst :: TCvSubst -> Bool
isValidTCvSubst :: TCvSubst -> Bool
isValidTCvSubst (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) =
  (VarSet
tenvFVs VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope) Bool -> Bool -> Bool
&&
  (VarSet
cenvFVs VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope)
  where
  tenvFVs :: VarSet
tenvFVs = TyVarEnv Type -> VarSet
tyCoVarsOfTypesSet TyVarEnv Type
tenv
  cenvFVs :: VarSet
cenvFVs = CoVarEnv Coercion -> VarSet
tyCoVarsOfCosSet CoVarEnv Coercion
cenv

-- | This checks if the substitution satisfies the invariant from
-- Note [The substitution invariant].
checkValidSubst :: HasCallStack => TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst :: TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) [Type]
tys [Coercion]
cos a
a
-- TODO (RAE): Change back to ASSERT
  = WARN( not (isValidTCvSubst subst),
             text "in_scope" <+> ppr in_scope $$
             text "tenv" <+> ppr tenv $$
             text "tenvFVs" <+> ppr (tyCoVarsOfTypesSet tenv) $$
             text "cenv" <+> ppr cenv $$
             text "cenvFVs" <+> ppr (tyCoVarsOfCosSet cenv) $$
             text "tys" <+> ppr tys $$
             text "cos" <+> ppr cos )
    WARN( not tysCosFVsInScope,
             text "in_scope" <+> ppr in_scope $$
             text "tenv" <+> ppr tenv $$
             text "cenv" <+> ppr cenv $$
             text "tys" <+> ppr tys $$
             text "cos" <+> ppr cos $$
             text "needInScope" <+> ppr needInScope )
    a
a
  where
  substDomain :: [Unique]
substDomain = TyVarEnv Type -> [Unique]
forall elt. UniqFM elt -> [Unique]
nonDetKeysUFM TyVarEnv Type
tenv [Unique] -> [Unique] -> [Unique]
forall a. [a] -> [a] -> [a]
++ CoVarEnv Coercion -> [Unique]
forall elt. UniqFM elt -> [Unique]
nonDetKeysUFM CoVarEnv Coercion
cenv
    -- It's OK to use nonDetKeysUFM here, because we only use this list to
    -- remove some elements from a set
  needInScope :: VarSet
needInScope = ([Type] -> VarSet
tyCoVarsOfTypes [Type]
tys VarSet -> VarSet -> VarSet
`unionVarSet` [Coercion] -> VarSet
tyCoVarsOfCos [Coercion]
cos)
                  VarSet -> [Unique] -> VarSet
forall a. UniqSet a -> [Unique] -> UniqSet a
`delListFromUniqSet_Directly` [Unique]
substDomain
  tysCosFVsInScope :: Bool
tysCosFVsInScope = VarSet
needInScope VarSet -> InScopeSet -> Bool
`varSetInScope` InScopeSet
in_scope


-- | Substitute within a 'Type'
-- The substitution has to satisfy the invariants described in
-- Note [The substitution invariant].
substTy :: HasCallStack => TCvSubst -> Type  -> Type
substTy :: TCvSubst -> Type -> Type
substTy TCvSubst
subst Type
ty
  | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Type
ty
  | Bool
otherwise             = TCvSubst -> [Type] -> [Coercion] -> Type -> Type
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [Type
ty] [] (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
                            TCvSubst -> Type -> Type
subst_ty TCvSubst
subst Type
ty

-- | Substitute within a 'Type' disabling the sanity checks.
-- The problems that the sanity checks in substTy catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substTyUnchecked to
-- substTy and remove this function. Please don't use in new code.
substTyUnchecked :: TCvSubst -> Type -> Type
substTyUnchecked :: TCvSubst -> Type -> Type
substTyUnchecked TCvSubst
subst Type
ty
                 | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Type
ty
                 | Bool
otherwise             = TCvSubst -> Type -> Type
subst_ty TCvSubst
subst Type
ty

-- | Substitute within several 'Type's
-- The substitution has to satisfy the invariants described in
-- Note [The substitution invariant].
substTys :: HasCallStack => TCvSubst -> [Type] -> [Type]
substTys :: TCvSubst -> [Type] -> [Type]
substTys TCvSubst
subst [Type]
tys
  | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Type]
tys
  | Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> [Type] -> [Type]
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [Type]
tys [] ([Type] -> [Type]) -> [Type] -> [Type]
forall a b. (a -> b) -> a -> b
$ (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst) [Type]
tys

-- | Substitute within several 'Type's disabling the sanity checks.
-- The problems that the sanity checks in substTys catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substTysUnchecked to
-- substTys and remove this function. Please don't use in new code.
substTysUnchecked :: TCvSubst -> [Type] -> [Type]
substTysUnchecked :: TCvSubst -> [Type] -> [Type]
substTysUnchecked TCvSubst
subst [Type]
tys
                 | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Type]
tys
                 | Bool
otherwise             = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst) [Type]
tys

-- | Substitute within a 'ThetaType'
-- The substitution has to satisfy the invariants described in
-- Note [The substitution invariant].
substTheta :: HasCallStack => TCvSubst -> ThetaType -> ThetaType
substTheta :: TCvSubst -> [Type] -> [Type]
substTheta = HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys

-- | Substitute within a 'ThetaType' disabling the sanity checks.
-- The problems that the sanity checks in substTys catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substThetaUnchecked to
-- substTheta and remove this function. Please don't use in new code.
substThetaUnchecked :: TCvSubst -> ThetaType -> ThetaType
substThetaUnchecked :: TCvSubst -> [Type] -> [Type]
substThetaUnchecked = TCvSubst -> [Type] -> [Type]
substTysUnchecked


subst_ty :: TCvSubst -> Type -> Type
-- subst_ty is the main workhorse for type substitution
--
-- Note that the in_scope set is poked only if we hit a forall
-- so it may often never be fully computed
subst_ty :: TCvSubst -> Type -> Type
subst_ty TCvSubst
subst Type
ty
   = Type -> Type
go Type
ty
  where
    go :: Type -> Type
go (TyVarTy Id
tv)      = TCvSubst -> Id -> Type
substTyVar TCvSubst
subst Id
tv
    go (AppTy Type
fun Type
arg)   = Type -> Type -> Type
mkAppTy (Type -> Type
go Type
fun) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
arg)
                -- The mkAppTy smart constructor is important
                -- we might be replacing (a Int), represented with App
                -- by [Int], represented with TyConApp
    go (TyConApp TyCon
tc [Type]
tys) = let args :: [Type]
args = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
go [Type]
tys
                           in  [Type]
args [Type] -> Type -> Type
forall a b. [a] -> b -> b
`seqList` TyCon -> [Type] -> Type
TyConApp TyCon
tc [Type]
args
    go (FunTy Type
arg Type
res)   = (Type -> Type -> Type
FunTy (Type -> Type -> Type) -> Type -> Type -> Type
forall a b. (a -> b) -> a -> b
$! Type -> Type
go Type
arg) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! Type -> Type
go Type
res
    go (ForAllTy (Bndr Id
tv ArgFlag
vis) Type
ty)
                         = case TCvSubst -> Id -> (TCvSubst, Id)
substVarBndrUnchecked TCvSubst
subst Id
tv of
                             (TCvSubst
subst', Id
tv') ->
                               (TyCoVarBinder -> Type -> Type
ForAllTy (TyCoVarBinder -> Type -> Type) -> TyCoVarBinder -> Type -> Type
forall a b. (a -> b) -> a -> b
$! ((Id -> ArgFlag -> TyCoVarBinder
forall var argf. var -> argf -> VarBndr var argf
Bndr (Id -> ArgFlag -> TyCoVarBinder) -> Id -> ArgFlag -> TyCoVarBinder
forall a b. (a -> b) -> a -> b
$! Id
tv') ArgFlag
vis)) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$!
                                            (TCvSubst -> Type -> Type
subst_ty TCvSubst
subst' Type
ty)
    go (LitTy TyLit
n)         = TyLit -> Type
LitTy (TyLit -> Type) -> TyLit -> Type
forall a b. (a -> b) -> a -> b
$! TyLit
n
    go (CastTy Type
ty Coercion
co)    = (Type -> Coercion -> Type
mkCastTy (Type -> Coercion -> Type) -> Type -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go Type
ty)) (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co)
    go (CoercionTy Coercion
co)   = Coercion -> Type
CoercionTy (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co)

substTyVar :: TCvSubst -> TyVar -> Type
substTyVar :: TCvSubst -> Id -> Type
substTyVar (TCvSubst InScopeSet
_ TyVarEnv Type
tenv CoVarEnv Coercion
_) Id
tv
  = ASSERT( isTyVar tv )
    case TyVarEnv Type -> Id -> Maybe Type
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv TyVarEnv Type
tenv Id
tv of
      Just Type
ty -> Type
ty
      Maybe Type
Nothing -> Id -> Type
TyVarTy Id
tv

substTyVars :: TCvSubst -> [TyVar] -> [Type]
substTyVars :: TCvSubst -> [Id] -> [Type]
substTyVars TCvSubst
subst = (Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ((Id -> Type) -> [Id] -> [Type]) -> (Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> a -> b
$ TCvSubst -> Id -> Type
substTyVar TCvSubst
subst

substTyCoVars :: TCvSubst -> [TyCoVar] -> [Type]
substTyCoVars :: TCvSubst -> [Id] -> [Type]
substTyCoVars TCvSubst
subst = (Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ((Id -> Type) -> [Id] -> [Type]) -> (Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> a -> b
$ TCvSubst -> Id -> Type
substTyCoVar TCvSubst
subst

substTyCoVar :: TCvSubst -> TyCoVar -> Type
substTyCoVar :: TCvSubst -> Id -> Type
substTyCoVar TCvSubst
subst Id
tv
  | Id -> Bool
isTyVar Id
tv = TCvSubst -> Id -> Type
substTyVar TCvSubst
subst Id
tv
  | Bool
otherwise = Coercion -> Type
CoercionTy (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$ TCvSubst -> Id -> Coercion
substCoVar TCvSubst
subst Id
tv

lookupTyVar :: TCvSubst -> TyVar  -> Maybe Type
        -- See Note [Extending the TCvSubst]
lookupTyVar :: TCvSubst -> Id -> Maybe Type
lookupTyVar (TCvSubst InScopeSet
_ TyVarEnv Type
tenv CoVarEnv Coercion
_) Id
tv
  = ASSERT( isTyVar tv )
    TyVarEnv Type -> Id -> Maybe Type
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv TyVarEnv Type
tenv Id
tv

-- | Substitute within a 'Coercion'
-- The substitution has to satisfy the invariants described in
-- Note [The substitution invariant].
substCo :: HasCallStack => TCvSubst -> Coercion -> Coercion
substCo :: TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst Coercion
co
  | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Coercion
co
  | Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> Coercion -> Coercion
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [] [Coercion
co] (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$ TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co

-- | Substitute within a 'Coercion' disabling sanity checks.
-- The problems that the sanity checks in substCo catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substCoUnchecked to
-- substCo and remove this function. Please don't use in new code.
substCoUnchecked :: TCvSubst -> Coercion -> Coercion
substCoUnchecked :: TCvSubst -> Coercion -> Coercion
substCoUnchecked TCvSubst
subst Coercion
co
  | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = Coercion
co
  | Bool
otherwise = TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co

-- | Substitute within several 'Coercion's
-- The substitution has to satisfy the invariants described in
-- Note [The substitution invariant].
substCos :: HasCallStack => TCvSubst -> [Coercion] -> [Coercion]
substCos :: TCvSubst -> [Coercion] -> [Coercion]
substCos TCvSubst
subst [Coercion]
cos
  | TCvSubst -> Bool
isEmptyTCvSubst TCvSubst
subst = [Coercion]
cos
  | Bool
otherwise = TCvSubst -> [Type] -> [Coercion] -> [Coercion] -> [Coercion]
forall a.
HasCallStack =>
TCvSubst -> [Type] -> [Coercion] -> a -> a
checkValidSubst TCvSubst
subst [] [Coercion]
cos ([Coercion] -> [Coercion]) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> a -> b
$ (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst) [Coercion]
cos

subst_co :: TCvSubst -> Coercion -> Coercion
subst_co :: TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst Coercion
co
  = Coercion -> Coercion
go Coercion
co
  where
    go_ty :: Type -> Type
    go_ty :: Type -> Type
go_ty = TCvSubst -> Type -> Type
subst_ty TCvSubst
subst

    go_mco :: MCoercion -> MCoercion
    go_mco :: MCoercion -> MCoercion
go_mco MCoercion
MRefl    = MCoercion
MRefl
    go_mco (MCo Coercion
co) = Coercion -> MCoercion
MCo (Coercion -> Coercion
go Coercion
co)

    go :: Coercion -> Coercion
    go :: Coercion -> Coercion
go (Refl Type
ty)             = Type -> Coercion
mkNomReflCo (Type -> Coercion) -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
ty)
    go (GRefl Role
r Type
ty MCoercion
mco)      = (Role -> Type -> MCoercion -> Coercion
mkGReflCo Role
r (Type -> MCoercion -> Coercion) -> Type -> MCoercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
ty)) (MCoercion -> Coercion) -> MCoercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (MCoercion -> MCoercion
go_mco MCoercion
mco)
    go (TyConAppCo Role
r TyCon
tc [Coercion]
args)= let args' :: [Coercion]
args' = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
args
                               in  [Coercion]
args' [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
r TyCon
tc [Coercion]
args'
    go (AppCo Coercion
co Coercion
arg)        = (Coercion -> Coercion -> Coercion
mkAppCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
arg
    go (ForAllCo Id
tv Coercion
kind_co Coercion
co)
      = case TCvSubst -> Id -> Coercion -> (TCvSubst, Id, Coercion)
substForAllCoBndrUnchecked TCvSubst
subst Id
tv Coercion
kind_co of
         (TCvSubst
subst', Id
tv', Coercion
kind_co') ->
          ((Id -> Coercion -> Coercion -> Coercion
mkForAllCo (Id -> Coercion -> Coercion -> Coercion)
-> Id -> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Id
tv') (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion
kind_co') (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! TCvSubst -> Coercion -> Coercion
subst_co TCvSubst
subst' Coercion
co
    go (FunCo Role
r Coercion
co1 Coercion
co2)     = (Role -> Coercion -> Coercion -> Coercion
mkFunCo Role
r (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co1) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co2
    go (CoVarCo Id
cv)          = TCvSubst -> Id -> Coercion
substCoVar TCvSubst
subst Id
cv
    go (AxiomInstCo CoAxiom Branched
con Int
ind [Coercion]
cos) = CoAxiom Branched -> Int -> [Coercion] -> Coercion
mkAxiomInstCo CoAxiom Branched
con Int
ind ([Coercion] -> Coercion) -> [Coercion] -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cos
    go (UnivCo UnivCoProvenance
p Role
r Type
t1 Type
t2)    = (((UnivCoProvenance -> Role -> Type -> Type -> Coercion
mkUnivCo (UnivCoProvenance -> Role -> Type -> Type -> Coercion)
-> UnivCoProvenance -> Role -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! UnivCoProvenance -> UnivCoProvenance
go_prov UnivCoProvenance
p) (Role -> Type -> Type -> Coercion)
-> Role -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! Role
r) (Type -> Type -> Coercion) -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$!
                                (Type -> Type
go_ty Type
t1)) (Type -> Coercion) -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! (Type -> Type
go_ty Type
t2)
    go (SymCo Coercion
co)            = Coercion -> Coercion
mkSymCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
    go (TransCo Coercion
co1 Coercion
co2)     = (Coercion -> Coercion -> Coercion
mkTransCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co1)) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co2)
    go (NthCo Role
r Int
d Coercion
co)        = HasDebugCallStack => Role -> Int -> Coercion -> Coercion
Role -> Int -> Coercion -> Coercion
mkNthCo Role
r Int
d (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
    go (LRCo LeftOrRight
lr Coercion
co)          = LeftOrRight -> Coercion -> Coercion
mkLRCo LeftOrRight
lr (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
    go (InstCo Coercion
co Coercion
arg)       = (Coercion -> Coercion -> Coercion
mkInstCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
arg
    go (KindCo Coercion
co)           = Coercion -> Coercion
mkKindCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
    go (SubCo Coercion
co)            = Coercion -> Coercion
mkSubCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
co)
    go (AxiomRuleCo CoAxiomRule
c [Coercion]
cs)    = let cs1 :: [Coercion]
cs1 = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cs
                                in [Coercion]
cs1 [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` CoAxiomRule -> [Coercion] -> Coercion
AxiomRuleCo CoAxiomRule
c [Coercion]
cs1
    go (HoleCo CoercionHole
h)            = CoercionHole -> Coercion
HoleCo (CoercionHole -> Coercion) -> CoercionHole -> Coercion
forall a b. (a -> b) -> a -> b
$! CoercionHole -> CoercionHole
go_hole CoercionHole
h

    go_prov :: UnivCoProvenance -> UnivCoProvenance
go_prov UnivCoProvenance
UnsafeCoerceProv     = UnivCoProvenance
UnsafeCoerceProv
    go_prov (PhantomProv Coercion
kco)    = Coercion -> UnivCoProvenance
PhantomProv (Coercion -> Coercion
go Coercion
kco)
    go_prov (ProofIrrelProv Coercion
kco) = Coercion -> UnivCoProvenance
ProofIrrelProv (Coercion -> Coercion
go Coercion
kco)
    go_prov p :: UnivCoProvenance
p@(PluginProv String
_)     = UnivCoProvenance
p

    -- See Note [Substituting in a coercion hole]
    go_hole :: CoercionHole -> CoercionHole
go_hole h :: CoercionHole
h@(CoercionHole { ch_co_var :: CoercionHole -> Id
ch_co_var = Id
cv })
      = CoercionHole
h { ch_co_var :: Id
ch_co_var = (Type -> Type) -> Id -> Id
updateVarType Type -> Type
go_ty Id
cv }

substForAllCoBndr :: TCvSubst -> TyCoVar -> KindCoercion
                  -> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndr :: TCvSubst -> Id -> Coercion -> (TCvSubst, Id, Coercion)
substForAllCoBndr TCvSubst
subst
  = Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoBndrUsing Bool
False (HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
substCo TCvSubst
subst) TCvSubst
subst

-- | Like 'substForAllCoBndr', but disables sanity checks.
-- The problems that the sanity checks in substCo catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substCoUnchecked to
-- substCo and remove this function. Please don't use in new code.
substForAllCoBndrUnchecked :: TCvSubst -> TyCoVar -> KindCoercion
                           -> (TCvSubst, TyCoVar, Coercion)
substForAllCoBndrUnchecked :: TCvSubst -> Id -> Coercion -> (TCvSubst, Id, Coercion)
substForAllCoBndrUnchecked TCvSubst
subst
  = Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoBndrUsing Bool
False (TCvSubst -> Coercion -> Coercion
substCoUnchecked TCvSubst
subst) TCvSubst
subst

-- See Note [Sym and ForAllCo]
substForAllCoBndrUsing :: Bool  -- apply sym to binder?
                       -> (Coercion -> Coercion)  -- transformation to kind co
                       -> TCvSubst -> TyCoVar -> KindCoercion
                       -> (TCvSubst, TyCoVar, KindCoercion)
substForAllCoBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoBndrUsing Bool
sym Coercion -> Coercion
sco TCvSubst
subst Id
old_var
  | Id -> Bool
isTyVar Id
old_var = Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoTyVarBndrUsing Bool
sym Coercion -> Coercion
sco TCvSubst
subst Id
old_var
  | Bool
otherwise       = Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoCoVarBndrUsing Bool
sym Coercion -> Coercion
sco TCvSubst
subst Id
old_var

substForAllCoTyVarBndrUsing :: Bool  -- apply sym to binder?
                            -> (Coercion -> Coercion)  -- transformation to kind co
                            -> TCvSubst -> TyVar -> KindCoercion
                            -> (TCvSubst, TyVar, KindCoercion)
substForAllCoTyVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoTyVarBndrUsing Bool
sym Coercion -> Coercion
sco (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
old_var Coercion
old_kind_co
  = ASSERT( isTyVar old_var )
    ( InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> Id -> InScopeSet
`extendInScopeSet` Id
new_var) TyVarEnv Type
new_env CoVarEnv Coercion
cenv
    , Id
new_var, Coercion
new_kind_co )
  where
    new_env :: TyVarEnv Type
new_env | Bool
no_change Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
sym = TyVarEnv Type -> Id -> TyVarEnv Type
forall a. VarEnv a -> Id -> VarEnv a
delVarEnv TyVarEnv Type
tenv Id
old_var
            | Bool
sym       = TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tenv Id
old_var (Type -> TyVarEnv Type) -> Type -> TyVarEnv Type
forall a b. (a -> b) -> a -> b
$
                          Id -> Type
TyVarTy Id
new_var Type -> Coercion -> Type
`CastTy` Coercion
new_kind_co
            | Bool
otherwise = TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tenv Id
old_var (Id -> Type
TyVarTy Id
new_var)

    no_kind_change :: Bool
no_kind_change = Coercion -> Bool
noFreeVarsOfCo Coercion
old_kind_co
    no_change :: Bool
no_change = Bool
no_kind_change Bool -> Bool -> Bool
&& (Id
new_var Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
old_var)

    new_kind_co :: Coercion
new_kind_co | Bool
no_kind_change = Coercion
old_kind_co
                | Bool
otherwise      = Coercion -> Coercion
sco Coercion
old_kind_co

    Pair Type
new_ki1 Type
_ = Coercion -> Pair Type
coercionKind Coercion
new_kind_co
    -- We could do substitution to (tyVarKind old_var). We don't do so because
    -- we already substituted new_kind_co, which contains the kind information
    -- we want. We don't want to do substitution once more. Also, in most cases,
    -- new_kind_co is a Refl, in which case coercionKind is really fast.

    new_var :: Id
new_var  = InScopeSet -> Id -> Id
uniqAway InScopeSet
in_scope (Id -> Type -> Id
setTyVarKind Id
old_var Type
new_ki1)

substForAllCoCoVarBndrUsing :: Bool  -- apply sym to binder?
                            -> (Coercion -> Coercion)  -- transformation to kind co
                            -> TCvSubst -> CoVar -> KindCoercion
                            -> (TCvSubst, CoVar, KindCoercion)
substForAllCoCoVarBndrUsing :: Bool
-> (Coercion -> Coercion)
-> TCvSubst
-> Id
-> Coercion
-> (TCvSubst, Id, Coercion)
substForAllCoCoVarBndrUsing Bool
sym Coercion -> Coercion
sco (TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv)
                            Id
old_var Coercion
old_kind_co
  = ASSERT( isCoVar old_var )
    ( InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> Id -> InScopeSet
`extendInScopeSet` Id
new_var) TyVarEnv Type
tenv CoVarEnv Coercion
new_cenv
    , Id
new_var, Coercion
new_kind_co )
  where
    new_cenv :: CoVarEnv Coercion
new_cenv | Bool
no_change Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
sym = CoVarEnv Coercion -> Id -> CoVarEnv Coercion
forall a. VarEnv a -> Id -> VarEnv a
delVarEnv CoVarEnv Coercion
cenv Id
old_var
             | Bool
otherwise = CoVarEnv Coercion -> Id -> Coercion -> CoVarEnv Coercion
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv CoVarEnv Coercion
cenv Id
old_var (Id -> Coercion
mkCoVarCo Id
new_var)

    no_kind_change :: Bool
no_kind_change = Coercion -> Bool
noFreeVarsOfCo Coercion
old_kind_co
    no_change :: Bool
no_change = Bool
no_kind_change Bool -> Bool -> Bool
&& (Id
new_var Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
old_var)

    new_kind_co :: Coercion
new_kind_co | Bool
no_kind_change = Coercion
old_kind_co
                | Bool
otherwise      = Coercion -> Coercion
sco Coercion
old_kind_co

    Pair Type
h1 Type
h2 = Coercion -> Pair Type
coercionKind Coercion
new_kind_co

    new_var :: Id
new_var       = InScopeSet -> Id -> Id
uniqAway InScopeSet
in_scope (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$ Name -> Type -> Id
mkCoVar (Id -> Name
varName Id
old_var) Type
new_var_type
    new_var_type :: Type
new_var_type  | Bool
sym       = Type
h2
                  | Bool
otherwise = Type
h1

substCoVar :: TCvSubst -> CoVar -> Coercion
substCoVar :: TCvSubst -> Id -> Coercion
substCoVar (TCvSubst InScopeSet
_ TyVarEnv Type
_ CoVarEnv Coercion
cenv) Id
cv
  = case CoVarEnv Coercion -> Id -> Maybe Coercion
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv CoVarEnv Coercion
cenv Id
cv of
      Just Coercion
co -> Coercion
co
      Maybe Coercion
Nothing -> Id -> Coercion
CoVarCo Id
cv

substCoVars :: TCvSubst -> [CoVar] -> [Coercion]
substCoVars :: TCvSubst -> [Id] -> [Coercion]
substCoVars TCvSubst
subst [Id]
cvs = (Id -> Coercion) -> [Id] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> Id -> Coercion
substCoVar TCvSubst
subst) [Id]
cvs

lookupCoVar :: TCvSubst -> Var -> Maybe Coercion
lookupCoVar :: TCvSubst -> Id -> Maybe Coercion
lookupCoVar (TCvSubst InScopeSet
_ TyVarEnv Type
_ CoVarEnv Coercion
cenv) Id
v = CoVarEnv Coercion -> Id -> Maybe Coercion
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv CoVarEnv Coercion
cenv Id
v

substTyVarBndr :: HasCallStack => TCvSubst -> TyVar -> (TCvSubst, TyVar)
substTyVarBndr :: TCvSubst -> Id -> (TCvSubst, Id)
substTyVarBndr = (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substTyVarBndrUsing HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy

substTyVarBndrs :: HasCallStack => TCvSubst -> [TyVar] -> (TCvSubst, [TyVar])
substTyVarBndrs :: TCvSubst -> [Id] -> (TCvSubst, [Id])
substTyVarBndrs = (TCvSubst -> Id -> (TCvSubst, Id))
-> TCvSubst -> [Id] -> (TCvSubst, [Id])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL HasCallStack => TCvSubst -> Id -> (TCvSubst, Id)
TCvSubst -> Id -> (TCvSubst, Id)
substTyVarBndr

substVarBndr :: HasCallStack => TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndr :: TCvSubst -> Id -> (TCvSubst, Id)
substVarBndr = (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substVarBndrUsing HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy

substVarBndrs :: HasCallStack => TCvSubst -> [TyCoVar] -> (TCvSubst, [TyCoVar])
substVarBndrs :: TCvSubst -> [Id] -> (TCvSubst, [Id])
substVarBndrs = (TCvSubst -> Id -> (TCvSubst, Id))
-> TCvSubst -> [Id] -> (TCvSubst, [Id])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL HasCallStack => TCvSubst -> Id -> (TCvSubst, Id)
TCvSubst -> Id -> (TCvSubst, Id)
substVarBndr

substCoVarBndr :: HasCallStack => TCvSubst -> CoVar -> (TCvSubst, CoVar)
substCoVarBndr :: TCvSubst -> Id -> (TCvSubst, Id)
substCoVarBndr = (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substCoVarBndrUsing HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy

-- | Like 'substVarBndr', but disables sanity checks.
-- The problems that the sanity checks in substTy catch are described in
-- Note [The substitution invariant].
-- The goal of #11371 is to migrate all the calls of substTyUnchecked to
-- substTy and remove this function. Please don't use in new code.
substVarBndrUnchecked :: TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUnchecked :: TCvSubst -> Id -> (TCvSubst, Id)
substVarBndrUnchecked = (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substVarBndrUsing TCvSubst -> Type -> Type
substTyUnchecked

substVarBndrUsing :: (TCvSubst -> Type -> Type)
                  -> TCvSubst -> TyCoVar -> (TCvSubst, TyCoVar)
substVarBndrUsing :: (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substVarBndrUsing TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Id
v
  | Id -> Bool
isTyVar Id
v = (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substTyVarBndrUsing TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Id
v
  | Bool
otherwise = (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substCoVarBndrUsing TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Id
v

-- | Substitute a tyvar in a binding position, returning an
-- extended subst and a new tyvar.
-- Use the supplied function to substitute in the kind
substTyVarBndrUsing
  :: (TCvSubst -> Type -> Type)  -- ^ Use this to substitute in the kind
  -> TCvSubst -> TyVar -> (TCvSubst, TyVar)
substTyVarBndrUsing :: (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substTyVarBndrUsing TCvSubst -> Type -> Type
subst_fn subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
old_var
  = ASSERT2( _no_capture, pprTyVar old_var $$ pprTyVar new_var $$ ppr subst )
    ASSERT( isTyVar old_var )
    (InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> Id -> InScopeSet
`extendInScopeSet` Id
new_var) TyVarEnv Type
new_env CoVarEnv Coercion
cenv, Id
new_var)
  where
    new_env :: TyVarEnv Type
new_env | Bool
no_change = TyVarEnv Type -> Id -> TyVarEnv Type
forall a. VarEnv a -> Id -> VarEnv a
delVarEnv TyVarEnv Type
tenv Id
old_var
            | Bool
otherwise = TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tenv Id
old_var (Id -> Type
TyVarTy Id
new_var)

    _no_capture :: Bool
_no_capture = Bool -> Bool
not (Id
new_var Id -> VarSet -> Bool
`elemVarSet` TyVarEnv Type -> VarSet
tyCoVarsOfTypesSet TyVarEnv Type
tenv)
    -- Assertion check that we are not capturing something in the substitution

    old_ki :: Type
old_ki = Id -> Type
tyVarKind Id
old_var
    no_kind_change :: Bool
no_kind_change = Type -> Bool
noFreeVarsOfType Type
old_ki -- verify that kind is closed
    no_change :: Bool
no_change = Bool
no_kind_change Bool -> Bool -> Bool
&& (Id
new_var Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
old_var)
        -- no_change means that the new_var is identical in
        -- all respects to the old_var (same unique, same kind)
        -- See Note [Extending the TCvSubst]
        --
        -- In that case we don't need to extend the substitution
        -- to map old to new.  But instead we must zap any
        -- current substitution for the variable. For example:
        --      (\x.e) with id_subst = [x |-> e']
        -- Here we must simply zap the substitution for x

    new_var :: Id
new_var | Bool
no_kind_change = InScopeSet -> Id -> Id
uniqAway InScopeSet
in_scope Id
old_var
            | Bool
otherwise = InScopeSet -> Id -> Id
uniqAway InScopeSet
in_scope (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$
                          Id -> Type -> Id
setTyVarKind Id
old_var (TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Type
old_ki)
        -- The uniqAway part makes sure the new variable is not already in scope

-- | Substitute a covar in a binding position, returning an
-- extended subst and a new covar.
-- Use the supplied function to substitute in the kind
substCoVarBndrUsing
  :: (TCvSubst -> Type -> Type)
  -> TCvSubst -> CoVar -> (TCvSubst, CoVar)
substCoVarBndrUsing :: (TCvSubst -> Type -> Type) -> TCvSubst -> Id -> (TCvSubst, Id)
substCoVarBndrUsing TCvSubst -> Type -> Type
subst_fn subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TyVarEnv Type
tenv CoVarEnv Coercion
cenv) Id
old_var
  = ASSERT( isCoVar old_var )
    (InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet
in_scope InScopeSet -> Id -> InScopeSet
`extendInScopeSet` Id
new_var) TyVarEnv Type
tenv CoVarEnv Coercion
new_cenv, Id
new_var)
  where
    new_co :: Coercion
new_co         = Id -> Coercion
mkCoVarCo Id
new_var
    no_kind_change :: Bool
no_kind_change = [Type] -> Bool
noFreeVarsOfTypes [Type
t1, Type
t2]
    no_change :: Bool
no_change      = Id
new_var Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
old_var Bool -> Bool -> Bool
&& Bool
no_kind_change

    new_cenv :: CoVarEnv Coercion
new_cenv | Bool
no_change = CoVarEnv Coercion -> Id -> CoVarEnv Coercion
forall a. VarEnv a -> Id -> VarEnv a
delVarEnv CoVarEnv Coercion
cenv Id
old_var
             | Bool
otherwise = CoVarEnv Coercion -> Id -> Coercion -> CoVarEnv Coercion
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv CoVarEnv Coercion
cenv Id
old_var Coercion
new_co

    new_var :: Id
new_var = InScopeSet -> Id -> Id
uniqAway InScopeSet
in_scope Id
subst_old_var
    subst_old_var :: Id
subst_old_var = Name -> Type -> Id
mkCoVar (Id -> Name
varName Id
old_var) Type
new_var_type

    (Type
_, Type
_, Type
t1, Type
t2, Role
role) = HasDebugCallStack => Id -> (Type, Type, Type, Type, Role)
Id -> (Type, Type, Type, Type, Role)
coVarKindsTypesRole Id
old_var
    t1' :: Type
t1' = TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Type
t1
    t2' :: Type
t2' = TCvSubst -> Type -> Type
subst_fn TCvSubst
subst Type
t2
    new_var_type :: Type
new_var_type = Role -> Type -> Type -> Type
mkCoercionType Role
role Type
t1' Type
t2'
                  -- It's important to do the substitution for coercions,
                  -- because they can have free type variables

cloneTyVarBndr :: TCvSubst -> TyVar -> Unique -> (TCvSubst, TyVar)
cloneTyVarBndr :: TCvSubst -> Id -> Unique -> (TCvSubst, Id)
cloneTyVarBndr subst :: TCvSubst
subst@(TCvSubst InScopeSet
in_scope TyVarEnv Type
tv_env CoVarEnv Coercion
cv_env) Id
tv Unique
uniq
  = ASSERT2( isTyVar tv, ppr tv )   -- I think it's only called on TyVars
    (InScopeSet -> TyVarEnv Type -> CoVarEnv Coercion -> TCvSubst
TCvSubst (InScopeSet -> Id -> InScopeSet
extendInScopeSet InScopeSet
in_scope Id
tv')
              (TyVarEnv Type -> Id -> Type -> TyVarEnv Type
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv TyVarEnv Type
tv_env Id
tv (Id -> Type
mkTyVarTy Id
tv')) CoVarEnv Coercion
cv_env, Id
tv')
  where
    old_ki :: Type
old_ki = Id -> Type
tyVarKind Id
tv
    no_kind_change :: Bool
no_kind_change = Type -> Bool
noFreeVarsOfType Type
old_ki -- verify that kind is closed

    tv1 :: Id
tv1 | Bool
no_kind_change = Id
tv
        | Bool
otherwise      = Id -> Type -> Id
setTyVarKind Id
tv (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst Type
old_ki)

    tv' :: Id
tv' = Id -> Unique -> Id
setVarUnique Id
tv1 Unique
uniq

cloneTyVarBndrs :: TCvSubst -> [TyVar] -> UniqSupply -> (TCvSubst, [TyVar])
cloneTyVarBndrs :: TCvSubst -> [Id] -> UniqSupply -> (TCvSubst, [Id])
cloneTyVarBndrs TCvSubst
subst []     UniqSupply
_usupply = (TCvSubst
subst, [])
cloneTyVarBndrs TCvSubst
subst (Id
t:[Id]
ts)  UniqSupply
usupply = (TCvSubst
subst'', Id
tvId -> [Id] -> [Id]
forall a. a -> [a] -> [a]
:[Id]
tvs)
  where
    (Unique
uniq, UniqSupply
usupply') = UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply UniqSupply
usupply
    (TCvSubst
subst' , Id
tv )   = TCvSubst -> Id -> Unique -> (TCvSubst, Id)
cloneTyVarBndr TCvSubst
subst Id
t Unique
uniq
    (TCvSubst
subst'', [Id]
tvs)   = TCvSubst -> [Id] -> UniqSupply -> (TCvSubst, [Id])
cloneTyVarBndrs TCvSubst
subst' [Id]
ts UniqSupply
usupply'

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

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

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

Note that any function which pretty-prints a @Type@ first converts the @Type@
to an @IfaceType@. See Note [IfaceType and pretty-printing] in IfaceType.

See Note [Precedence in types] in BasicTypes.
-}

--------------------------------------------------------
-- When pretty-printing types, we convert to IfaceType,
--   and pretty-print that.
-- See Note [Pretty printing via IfaceSyn] in PprTyThing
--------------------------------------------------------

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

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

pprPrecTypeX :: TidyEnv -> PprPrec -> Type -> SDoc
pprPrecTypeX :: TidyEnv -> PprPrec -> Type -> SDoc
pprPrecTypeX TidyEnv
env PprPrec
prec Type
ty
  = (PprStyle -> SDoc) -> SDoc
getPprStyle ((PprStyle -> SDoc) -> SDoc) -> (PprStyle -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \PprStyle
sty ->
    if PprStyle -> Bool
debugStyle PprStyle
sty           -- Use debugPprType when in
    then PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
prec Type
ty   -- when in debug-style
    else PprPrec -> IfaceType -> SDoc
pprPrecIfaceType PprPrec
prec (TidyEnv -> Type -> PprStyle -> IfaceType
tidyToIfaceTypeStyX TidyEnv
env Type
ty PprStyle
sty)

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

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

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

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

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

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

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

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

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

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

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

------------------
instance Outputable Type where
    ppr :: Type -> SDoc
ppr Type
ty = Type -> SDoc
pprType Type
ty

instance Outputable TyLit where
   ppr :: TyLit -> SDoc
ppr = TyLit -> SDoc
pprTyLit

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

pprForAll :: [TyCoVarBinder] -> SDoc
pprForAll :: [TyCoVarBinder] -> SDoc
pprForAll [TyCoVarBinder]
tvs = [IfaceForAllBndr] -> SDoc
pprIfaceForAll ((TyCoVarBinder -> IfaceForAllBndr)
-> [TyCoVarBinder] -> [IfaceForAllBndr]
forall a b. (a -> b) -> [a] -> [b]
map TyCoVarBinder -> IfaceForAllBndr
toIfaceForAllBndr [TyCoVarBinder]
tvs)

-- | Print a user-level forall; see Note [When to print foralls]
pprUserForAll :: [TyCoVarBinder] -> SDoc
pprUserForAll :: [TyCoVarBinder] -> SDoc
pprUserForAll = [IfaceForAllBndr] -> SDoc
pprUserIfaceForAll ([IfaceForAllBndr] -> SDoc)
-> ([TyCoVarBinder] -> [IfaceForAllBndr])
-> [TyCoVarBinder]
-> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TyCoVarBinder -> IfaceForAllBndr)
-> [TyCoVarBinder] -> [IfaceForAllBndr]
forall a b. (a -> b) -> [a] -> [b]
map TyCoVarBinder -> IfaceForAllBndr
toIfaceForAllBndr

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

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

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

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

instance Outputable TyCoBinder where
  ppr :: TyCoBinder -> SDoc
ppr (Anon Type
ty) = String -> SDoc
text String
"[anon]" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty
  ppr (Named (Bndr Id
v ArgFlag
Required))  = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
v
  ppr (Named (Bndr Id
v ArgFlag
Specified)) = Char -> SDoc
char Char
'@' SDoc -> SDoc -> SDoc
<> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
v
  ppr (Named (Bndr Id
v ArgFlag
Inferred))  = SDoc -> SDoc
braces (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
v)

-----------------
instance Outputable Coercion where -- defined here to avoid orphans
  ppr :: Coercion -> SDoc
ppr = Coercion -> SDoc
pprCo

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

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

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

debug_ppr_ty PprPrec
prec (FunTy Type
arg Type
res)
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    [SDoc] -> SDoc
sep [PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
funPrec Type
arg, SDoc
arrow SDoc -> SDoc -> SDoc
<+> PprPrec -> Type -> SDoc
debug_ppr_ty PprPrec
prec Type
res]

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

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

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

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

debug_ppr_ty PprPrec
prec ty :: Type
ty@(ForAllTy {})
  | ([TyCoVarBinder]
tvs, Type
body) <- Type -> ([TyCoVarBinder], Type)
split Type
ty
  = PprPrec -> PprPrec -> SDoc -> SDoc
maybeParen PprPrec
prec PprPrec
funPrec (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
    SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text String
"forall" SDoc -> SDoc -> SDoc
<+> [SDoc] -> SDoc
fsep ((TyCoVarBinder -> SDoc) -> [TyCoVarBinder] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map TyCoVarBinder -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVarBinder]
tvs) SDoc -> SDoc -> SDoc
<> SDoc
dot)
         -- The (map ppr tvs) will print kind-annotated
         -- tvs, because we are (usually) in debug-style
       Int
2 (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
body)
  where
    split :: Type -> ([TyCoVarBinder], Type)
split Type
ty | ForAllTy TyCoVarBinder
tv Type
ty' <- Type
ty
             , ([TyCoVarBinder]
tvs, Type
body) <- Type -> ([TyCoVarBinder], Type)
split Type
ty'
             = (TyCoVarBinder
tvTyCoVarBinder -> [TyCoVarBinder] -> [TyCoVarBinder]
forall a. a -> [a] -> [a]
:[TyCoVarBinder]
tvs, Type
body)
             | Bool
otherwise
             = ([], Type
ty)

{-
Note [When to print foralls]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mostly we want to print top-level foralls when (and only when) the user specifies
-fprint-explicit-foralls.  But when kind polymorphism is at work, that suppresses
too much information; see Trac #9018.

So I'm trying out this rule: print explicit foralls if
  a) User specifies -fprint-explicit-foralls, or
  b) Any of the quantified type variables has a kind
     that mentions a kind variable

This catches common situations, such as a type siguature
     f :: m a
which means
      f :: forall k. forall (m :: k->*) (a :: k). m a
We really want to see both the "forall k" and the kind signatures
on m and a.  The latter comes from pprTCvBndr.

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

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

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

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

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

   (~>) a b -> b

See Trac #2766.
-}

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

pprDataConWithArgs :: DataCon -> SDoc
pprDataConWithArgs :: DataCon -> SDoc
pprDataConWithArgs DataCon
dc = [SDoc] -> SDoc
sep [SDoc
forAllDoc, SDoc
thetaDoc, DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc SDoc -> SDoc -> SDoc
<+> SDoc
argsDoc]
  where
    ([Id]
_univ_tvs, [Id]
_ex_tvs, [EqSpec]
_eq_spec, [Type]
theta, [Type]
arg_tys, Type
_res_ty) = DataCon -> ([Id], [Id], [EqSpec], [Type], [Type], Type)
dataConFullSig DataCon
dc
    user_bndrs :: [TyCoVarBinder]
user_bndrs = DataCon -> [TyCoVarBinder]
dataConUserTyVarBinders DataCon
dc
    forAllDoc :: SDoc
forAllDoc  = [TyCoVarBinder] -> SDoc
pprUserForAll [TyCoVarBinder]
user_bndrs
    thetaDoc :: SDoc
thetaDoc   = [Type] -> SDoc
pprThetaArrowTy [Type]
theta
    argsDoc :: SDoc
argsDoc    = [SDoc] -> SDoc
hsep ((Type -> SDoc) -> [Type] -> [SDoc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> SDoc
pprParendType [Type]
arg_tys)


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

------------------
-- | Display all kind information (with @-fprint-explicit-kinds@) when the
-- provided 'Bool' argument is 'True'.
-- See @Note [Kind arguments in error messages]@ in "TcErrors".
pprWithExplicitKindsWhen :: Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen :: Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen Bool
b
  = (DynFlags -> DynFlags) -> SDoc -> SDoc
updSDocDynFlags ((DynFlags -> DynFlags) -> SDoc -> SDoc)
-> (DynFlags -> DynFlags) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags ->
      if Bool
b then DynFlags -> GeneralFlag -> DynFlags
gopt_set DynFlags
dflags GeneralFlag
Opt_PrintExplicitKinds
           else DynFlags
dflags

{-
%************************************************************************
%*                                                                      *
\subsection{TidyType}
%*                                                                      *
%************************************************************************
-}

-- | This tidies up a type for printing in an error message, or in
-- an interface file.
--
-- It doesn't change the uniques at all, just the print names.
tidyVarBndrs :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
tidyVarBndrs :: TidyEnv -> [Id] -> (TidyEnv, [Id])
tidyVarBndrs TidyEnv
tidy_env [Id]
tvs
  = (TidyEnv -> Id -> (TidyEnv, Id))
-> TidyEnv -> [Id] -> (TidyEnv, [Id])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL TidyEnv -> Id -> (TidyEnv, Id)
tidyVarBndr ([Id] -> TidyEnv -> TidyEnv
avoidNameClashes [Id]
tvs TidyEnv
tidy_env) [Id]
tvs

tidyVarBndr :: TidyEnv -> TyCoVar -> (TidyEnv, TyCoVar)
tidyVarBndr :: TidyEnv -> Id -> (TidyEnv, Id)
tidyVarBndr tidy_env :: TidyEnv
tidy_env@(TidyOccEnv
occ_env, VarEnv Id
subst) Id
var
  = case TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
tidyOccName TidyOccEnv
occ_env (Id -> OccName
getHelpfulOccName Id
var) of
      (TidyOccEnv
occ_env', OccName
occ') -> ((TidyOccEnv
occ_env', VarEnv Id
subst'), Id
var')
        where
          subst' :: VarEnv Id
subst' = VarEnv Id -> Id -> Id -> VarEnv Id
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv VarEnv Id
subst Id
var Id
var'
          var' :: Id
var'   = Id -> Type -> Id
setVarType (Id -> Name -> Id
setVarName Id
var Name
name') Type
type'
          type' :: Type
type'  = TidyEnv -> Type -> Type
tidyType TidyEnv
tidy_env (Id -> Type
varType Id
var)
          name' :: Name
name'  = Name -> OccName -> Name
tidyNameOcc Name
name OccName
occ'
          name :: Name
name   = Id -> Name
varName Id
var

avoidNameClashes :: [TyCoVar] -> TidyEnv -> TidyEnv
-- Seed the occ_env with clashes among the names, see
-- Node [Tidying multiple names at once] in OccName
avoidNameClashes :: [Id] -> TidyEnv -> TidyEnv
avoidNameClashes [Id]
tvs (TidyOccEnv
occ_env, VarEnv Id
subst)
  = (TidyOccEnv -> [OccName] -> TidyOccEnv
avoidClashesOccEnv TidyOccEnv
occ_env [OccName]
occs, VarEnv Id
subst)
  where
    occs :: [OccName]
occs = (Id -> OccName) -> [Id] -> [OccName]
forall a b. (a -> b) -> [a] -> [b]
map Id -> OccName
getHelpfulOccName [Id]
tvs

getHelpfulOccName :: TyCoVar -> OccName
-- A TcTyVar with a System Name is probably a
-- unification variable; when we tidy them we give them a trailing
-- "0" (or 1 etc) so that they don't take precedence for the
-- un-modified name. Plus, indicating a unification variable in
-- this way is a helpful clue for users
getHelpfulOccName :: Id -> OccName
getHelpfulOccName Id
tv
  | Name -> Bool
isSystemName Name
name, Id -> Bool
isTcTyVar Id
tv
  = String -> OccName
mkTyVarOcc (OccName -> String
occNameString OccName
occ String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"0")
  | Bool
otherwise
  = OccName
occ
  where
   name :: Name
name = Id -> Name
varName Id
tv
   occ :: OccName
occ  = Name -> OccName
forall a. NamedThing a => a -> OccName
getOccName Name
name

tidyTyCoVarBinder :: TidyEnv -> VarBndr TyCoVar vis
                  -> (TidyEnv, VarBndr TyCoVar vis)
tidyTyCoVarBinder :: TidyEnv -> VarBndr Id vis -> (TidyEnv, VarBndr Id vis)
tidyTyCoVarBinder TidyEnv
tidy_env (Bndr Id
tv vis
vis)
  = (TidyEnv
tidy_env', Id -> vis -> VarBndr Id vis
forall var argf. var -> argf -> VarBndr var argf
Bndr Id
tv' vis
vis)
  where
    (TidyEnv
tidy_env', Id
tv') = TidyEnv -> Id -> (TidyEnv, Id)
tidyVarBndr TidyEnv
tidy_env Id
tv

tidyTyCoVarBinders :: TidyEnv -> [VarBndr TyCoVar vis]
                   -> (TidyEnv, [VarBndr TyCoVar vis])
tidyTyCoVarBinders :: TidyEnv -> [VarBndr Id vis] -> (TidyEnv, [VarBndr Id vis])
tidyTyCoVarBinders = (TidyEnv -> VarBndr Id vis -> (TidyEnv, VarBndr Id vis))
-> TidyEnv -> [VarBndr Id vis] -> (TidyEnv, [VarBndr Id vis])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL TidyEnv -> VarBndr Id vis -> (TidyEnv, VarBndr Id vis)
forall vis. TidyEnv -> VarBndr Id vis -> (TidyEnv, VarBndr Id vis)
tidyTyCoVarBinder

---------------
tidyFreeTyCoVars :: TidyEnv -> [TyCoVar] -> TidyEnv
-- ^ Add the free 'TyVar's to the env in tidy form,
-- so that we can tidy the type they are free in
tidyFreeTyCoVars :: TidyEnv -> [Id] -> TidyEnv
tidyFreeTyCoVars (TidyOccEnv
full_occ_env, VarEnv Id
var_env) [Id]
tyvars
  = (TidyEnv, [Id]) -> TidyEnv
forall a b. (a, b) -> a
fst (TidyEnv -> [Id] -> (TidyEnv, [Id])
tidyOpenTyCoVars (TidyOccEnv
full_occ_env, VarEnv Id
var_env) [Id]
tyvars)

---------------
tidyOpenTyCoVars :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
tidyOpenTyCoVars :: TidyEnv -> [Id] -> (TidyEnv, [Id])
tidyOpenTyCoVars TidyEnv
env [Id]
tyvars = (TidyEnv -> Id -> (TidyEnv, Id))
-> TidyEnv -> [Id] -> (TidyEnv, [Id])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL TidyEnv -> Id -> (TidyEnv, Id)
tidyOpenTyCoVar TidyEnv
env [Id]
tyvars

---------------
tidyOpenTyCoVar :: TidyEnv -> TyCoVar -> (TidyEnv, TyCoVar)
-- ^ Treat a new 'TyCoVar' as a binder, and give it a fresh tidy name
-- using the environment if one has not already been allocated. See
-- also 'tidyVarBndr'
tidyOpenTyCoVar :: TidyEnv -> Id -> (TidyEnv, Id)
tidyOpenTyCoVar env :: TidyEnv
env@(TidyOccEnv
_, VarEnv Id
subst) Id
tyvar
  = case VarEnv Id -> Id -> Maybe Id
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv VarEnv Id
subst Id
tyvar of
        Just Id
tyvar' -> (TidyEnv
env, Id
tyvar')              -- Already substituted
        Maybe Id
Nothing     ->
          let env' :: TidyEnv
env' = TidyEnv -> [Id] -> TidyEnv
tidyFreeTyCoVars TidyEnv
env (Type -> [Id]
tyCoVarsOfTypeList (Id -> Type
tyVarKind Id
tyvar))
          in TidyEnv -> Id -> (TidyEnv, Id)
tidyVarBndr TidyEnv
env' Id
tyvar  -- Treat it as a binder

---------------
tidyTyCoVarOcc :: TidyEnv -> TyCoVar -> TyCoVar
tidyTyCoVarOcc :: TidyEnv -> Id -> Id
tidyTyCoVarOcc env :: TidyEnv
env@(TidyOccEnv
_, VarEnv Id
subst) Id
tv
  = case VarEnv Id -> Id -> Maybe Id
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv VarEnv Id
subst Id
tv of
        Maybe Id
Nothing  -> (Type -> Type) -> Id -> Id
updateVarType (TidyEnv -> Type -> Type
tidyType TidyEnv
env) Id
tv
        Just Id
tv' -> Id
tv'

---------------
tidyTypes :: TidyEnv -> [Type] -> [Type]
tidyTypes :: TidyEnv -> [Type] -> [Type]
tidyTypes TidyEnv
env [Type]
tys = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TidyEnv -> Type -> Type
tidyType TidyEnv
env) [Type]
tys

---------------
tidyType :: TidyEnv -> Type -> Type
tidyType :: TidyEnv -> Type -> Type
tidyType TidyEnv
_   (LitTy TyLit
n)            = TyLit -> Type
LitTy TyLit
n
tidyType TidyEnv
env (TyVarTy Id
tv)         = Id -> Type
TyVarTy (TidyEnv -> Id -> Id
tidyTyCoVarOcc TidyEnv
env Id
tv)
tidyType TidyEnv
env (TyConApp TyCon
tycon [Type]
tys) = let args :: [Type]
args = TidyEnv -> [Type] -> [Type]
tidyTypes TidyEnv
env [Type]
tys
                                    in [Type]
args [Type] -> Type -> Type
forall a b. [a] -> b -> b
`seqList` TyCon -> [Type] -> Type
TyConApp TyCon
tycon [Type]
args
tidyType TidyEnv
env (AppTy Type
fun Type
arg)      = (Type -> Type -> Type
AppTy (Type -> Type -> Type) -> Type -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
fun)) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
arg)
tidyType TidyEnv
env (FunTy Type
fun Type
arg)      = (Type -> Type -> Type
FunTy (Type -> Type -> Type) -> Type -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
fun)) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
arg)
tidyType TidyEnv
env (ty :: Type
ty@(ForAllTy{}))    = [(Id, ArgFlag)] -> Type -> Type
mkForAllTys' ([Id] -> [ArgFlag] -> [(Id, ArgFlag)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Id]
tvs' [ArgFlag]
vis) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! TidyEnv -> Type -> Type
tidyType TidyEnv
env' Type
body_ty
  where
    ([Id]
tvs, [ArgFlag]
vis, Type
body_ty) = Type -> ([Id], [ArgFlag], Type)
splitForAllTys' Type
ty
    (TidyEnv
env', [Id]
tvs') = TidyEnv -> [Id] -> (TidyEnv, [Id])
tidyVarBndrs TidyEnv
env [Id]
tvs
tidyType TidyEnv
env (CastTy Type
ty Coercion
co)       = (Type -> Coercion -> Type
CastTy (Type -> Coercion -> Type) -> Type -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
ty) (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Coercion -> Coercion
tidyCo TidyEnv
env Coercion
co)
tidyType TidyEnv
env (CoercionTy Coercion
co)      = Coercion -> Type
CoercionTy (Coercion -> Type) -> Coercion -> Type
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Coercion -> Coercion
tidyCo TidyEnv
env Coercion
co)


-- The following two functions differ from mkForAllTys and splitForAllTys in that
-- they expect/preserve the ArgFlag argument. Thes belong to types/Type.hs, but
-- how should they be named?
mkForAllTys' :: [(TyCoVar, ArgFlag)] -> Type -> Type
mkForAllTys' :: [(Id, ArgFlag)] -> Type -> Type
mkForAllTys' [(Id, ArgFlag)]
tvvs Type
ty = ((Id, ArgFlag) -> Type -> Type) -> Type -> [(Id, ArgFlag)] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Id, ArgFlag) -> Type -> Type
strictMkForAllTy Type
ty [(Id, ArgFlag)]
tvvs
  where
    strictMkForAllTy :: (Id, ArgFlag) -> Type -> Type
strictMkForAllTy (Id
tv,ArgFlag
vis) Type
ty = (TyCoVarBinder -> Type -> Type
ForAllTy (TyCoVarBinder -> Type -> Type) -> TyCoVarBinder -> Type -> Type
forall a b. (a -> b) -> a -> b
$! ((Id -> ArgFlag -> TyCoVarBinder
forall var argf. var -> argf -> VarBndr var argf
Bndr (Id -> ArgFlag -> TyCoVarBinder) -> Id -> ArgFlag -> TyCoVarBinder
forall a b. (a -> b) -> a -> b
$! Id
tv) (ArgFlag -> TyCoVarBinder) -> ArgFlag -> TyCoVarBinder
forall a b. (a -> b) -> a -> b
$! ArgFlag
vis)) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$! Type
ty

splitForAllTys' :: Type -> ([TyCoVar], [ArgFlag], Type)
splitForAllTys' :: Type -> ([Id], [ArgFlag], Type)
splitForAllTys' Type
ty = Type -> [Id] -> [ArgFlag] -> ([Id], [ArgFlag], Type)
go Type
ty [] []
  where
    go :: Type -> [Id] -> [ArgFlag] -> ([Id], [ArgFlag], Type)
go (ForAllTy (Bndr Id
tv ArgFlag
vis) Type
ty) [Id]
tvs [ArgFlag]
viss = Type -> [Id] -> [ArgFlag] -> ([Id], [ArgFlag], Type)
go Type
ty (Id
tvId -> [Id] -> [Id]
forall a. a -> [a] -> [a]
:[Id]
tvs) (ArgFlag
visArgFlag -> [ArgFlag] -> [ArgFlag]
forall a. a -> [a] -> [a]
:[ArgFlag]
viss)
    go Type
ty                          [Id]
tvs [ArgFlag]
viss = ([Id] -> [Id]
forall a. [a] -> [a]
reverse [Id]
tvs, [ArgFlag] -> [ArgFlag]
forall a. [a] -> [a]
reverse [ArgFlag]
viss, Type
ty)


---------------
-- | Grabs the free type variables, tidies them
-- and then uses 'tidyType' to work over the type itself
tidyOpenTypes :: TidyEnv -> [Type] -> (TidyEnv, [Type])
tidyOpenTypes :: TidyEnv -> [Type] -> (TidyEnv, [Type])
tidyOpenTypes TidyEnv
env [Type]
tys
  = (TidyEnv
env', TidyEnv -> [Type] -> [Type]
tidyTypes (TidyOccEnv
trimmed_occ_env, VarEnv Id
var_env) [Type]
tys)
  where
    (env' :: TidyEnv
env'@(TidyOccEnv
_, VarEnv Id
var_env), [Id]
tvs') = TidyEnv -> [Id] -> (TidyEnv, [Id])
tidyOpenTyCoVars TidyEnv
env ([Id] -> (TidyEnv, [Id])) -> [Id] -> (TidyEnv, [Id])
forall a b. (a -> b) -> a -> b
$
                                [Type] -> [Id]
tyCoVarsOfTypesWellScoped [Type]
tys
    trimmed_occ_env :: TidyOccEnv
trimmed_occ_env = [OccName] -> TidyOccEnv
initTidyOccEnv ((Id -> OccName) -> [Id] -> [OccName]
forall a b. (a -> b) -> [a] -> [b]
map Id -> OccName
forall a. NamedThing a => a -> OccName
getOccName [Id]
tvs')
      -- The idea here was that we restrict the new TidyEnv to the
      -- _free_ vars of the types, so that we don't gratuitously rename
      -- the _bound_ variables of the types.

---------------
tidyOpenType :: TidyEnv -> Type -> (TidyEnv, Type)
tidyOpenType :: TidyEnv -> Type -> (TidyEnv, Type)
tidyOpenType TidyEnv
env Type
ty = let (TidyEnv
env', [Type
ty']) = TidyEnv -> [Type] -> (TidyEnv, [Type])
tidyOpenTypes TidyEnv
env [Type
ty] in
                      (TidyEnv
env', Type
ty')

---------------
-- | Calls 'tidyType' on a top-level type (i.e. with an empty tidying environment)
tidyTopType :: Type -> Type
tidyTopType :: Type -> Type
tidyTopType Type
ty = TidyEnv -> Type -> Type
tidyType TidyEnv
emptyTidyEnv Type
ty

---------------
tidyOpenKind :: TidyEnv -> Kind -> (TidyEnv, Kind)
tidyOpenKind :: TidyEnv -> Type -> (TidyEnv, Type)
tidyOpenKind = TidyEnv -> Type -> (TidyEnv, Type)
tidyOpenType

tidyKind :: TidyEnv -> Kind -> Kind
tidyKind :: TidyEnv -> Type -> Type
tidyKind = TidyEnv -> Type -> Type
tidyType

----------------
tidyCo :: TidyEnv -> Coercion -> Coercion
tidyCo :: TidyEnv -> Coercion -> Coercion
tidyCo env :: TidyEnv
env@(TidyOccEnv
_, VarEnv Id
subst) Coercion
co
  = Coercion -> Coercion
go Coercion
co
  where
    go_mco :: MCoercion -> MCoercion
go_mco MCoercion
MRefl    = MCoercion
MRefl
    go_mco (MCo Coercion
co) = Coercion -> MCoercion
MCo (Coercion -> Coercion
go Coercion
co)

    go :: Coercion -> Coercion
go (Refl Type
ty)             = Type -> Coercion
Refl (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
ty)
    go (GRefl Role
r Type
ty MCoercion
mco)      = Role -> Type -> MCoercion -> Coercion
GRefl Role
r (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
ty) (MCoercion -> Coercion) -> MCoercion -> Coercion
forall a b. (a -> b) -> a -> b
$! MCoercion -> MCoercion
go_mco MCoercion
mco
    go (TyConAppCo Role
r TyCon
tc [Coercion]
cos) = let args :: [Coercion]
args = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cos
                               in [Coercion]
args [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` Role -> TyCon -> [Coercion] -> Coercion
TyConAppCo Role
r TyCon
tc [Coercion]
args
    go (AppCo Coercion
co1 Coercion
co2)       = (Coercion -> Coercion -> Coercion
AppCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co1) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co2
    go (ForAllCo Id
tv Coercion
h Coercion
co)    = ((Id -> Coercion -> Coercion -> Coercion
ForAllCo (Id -> Coercion -> Coercion -> Coercion)
-> Id -> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Id
tvp) (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (Coercion -> Coercion
go Coercion
h)) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! (TidyEnv -> Coercion -> Coercion
tidyCo TidyEnv
envp Coercion
co)
                               where (TidyEnv
envp, Id
tvp) = TidyEnv -> Id -> (TidyEnv, Id)
tidyVarBndr TidyEnv
env Id
tv
            -- the case above duplicates a bit of work in tidying h and the kind
            -- of tv. But the alternative is to use coercionKind, which seems worse.
    go (FunCo Role
r Coercion
co1 Coercion
co2)     = (Role -> Coercion -> Coercion -> Coercion
FunCo Role
r (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co1) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co2
    go (CoVarCo Id
cv)          = case VarEnv Id -> Id -> Maybe Id
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv VarEnv Id
subst Id
cv of
                                 Maybe Id
Nothing  -> Id -> Coercion
CoVarCo Id
cv
                                 Just Id
cv' -> Id -> Coercion
CoVarCo Id
cv'
    go (HoleCo CoercionHole
h)            = CoercionHole -> Coercion
HoleCo CoercionHole
h
    go (AxiomInstCo CoAxiom Branched
con Int
ind [Coercion]
cos) = let args :: [Coercion]
args = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Coercion
go [Coercion]
cos
                               in  [Coercion]
args [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` CoAxiom Branched -> Int -> [Coercion] -> Coercion
AxiomInstCo CoAxiom Branched
con Int
ind [Coercion]
args
    go (UnivCo UnivCoProvenance
p Role
r Type
t1 Type
t2)    = (((UnivCoProvenance -> Role -> Type -> Type -> Coercion
UnivCo (UnivCoProvenance -> Role -> Type -> Type -> Coercion)
-> UnivCoProvenance -> Role -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! (UnivCoProvenance -> UnivCoProvenance
go_prov UnivCoProvenance
p)) (Role -> Type -> Type -> Coercion)
-> Role -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! Role
r) (Type -> Type -> Coercion) -> Type -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$!
                                TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
t1) (Type -> Coercion) -> Type -> Coercion
forall a b. (a -> b) -> a -> b
$! TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
t2
    go (SymCo Coercion
co)            = Coercion -> Coercion
SymCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co
    go (TransCo Coercion
co1 Coercion
co2)     = (Coercion -> Coercion -> Coercion
TransCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co1) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co2
    go (NthCo Role
r Int
d Coercion
co)        = Role -> Int -> Coercion -> Coercion
NthCo Role
r Int
d (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co
    go (LRCo LeftOrRight
lr Coercion
co)          = LeftOrRight -> Coercion -> Coercion
LRCo LeftOrRight
lr (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co
    go (InstCo Coercion
co Coercion
ty)        = (Coercion -> Coercion -> Coercion
InstCo (Coercion -> Coercion -> Coercion)
-> Coercion -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co) (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
ty
    go (KindCo Coercion
co)           = Coercion -> Coercion
KindCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co
    go (SubCo Coercion
co)            = Coercion -> Coercion
SubCo (Coercion -> Coercion) -> Coercion -> Coercion
forall a b. (a -> b) -> a -> b
$! Coercion -> Coercion
go Coercion
co
    go (AxiomRuleCo CoAxiomRule
ax [Coercion]
cos)  = let cos1 :: [Coercion]
cos1 = TidyEnv -> [Coercion] -> [Coercion]
tidyCos TidyEnv
env [Coercion]
cos
                               in [Coercion]
cos1 [Coercion] -> Coercion -> Coercion
forall a b. [a] -> b -> b
`seqList` CoAxiomRule -> [Coercion] -> Coercion
AxiomRuleCo CoAxiomRule
ax [Coercion]
cos1

    go_prov :: UnivCoProvenance -> UnivCoProvenance
go_prov UnivCoProvenance
UnsafeCoerceProv    = UnivCoProvenance
UnsafeCoerceProv
    go_prov (PhantomProv Coercion
co)    = Coercion -> UnivCoProvenance
PhantomProv (Coercion -> Coercion
go Coercion
co)
    go_prov (ProofIrrelProv Coercion
co) = Coercion -> UnivCoProvenance
ProofIrrelProv (Coercion -> Coercion
go Coercion
co)
    go_prov p :: UnivCoProvenance
p@(PluginProv String
_)    = UnivCoProvenance
p

tidyCos :: TidyEnv -> [Coercion] -> [Coercion]
tidyCos :: TidyEnv -> [Coercion] -> [Coercion]
tidyCos TidyEnv
env = (Coercion -> Coercion) -> [Coercion] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map (TidyEnv -> Coercion -> Coercion
tidyCo TidyEnv
env)


{- *********************************************************************
*                                                                      *
                   typeSize, coercionSize
*                                                                      *
********************************************************************* -}

-- NB: We put typeSize/coercionSize here because they are mutually
--     recursive, and have the CPR property.  If we have mutual
--     recursion across a hi-boot file, we don't get the CPR property
--     and these functions allocate a tremendous amount of rubbish.
--     It's not critical (because typeSize is really only used in
--     debug mode, but I tripped over an example (T5642) in which
--     typeSize was one of the biggest single allocators in all of GHC.
--     And it's easy to fix, so I did.

-- NB: typeSize does not respect `eqType`, in that two types that
--     are `eqType` may return different sizes. This is OK, because this
--     function is used only in reporting, not decision-making.

typeSize :: Type -> Int
typeSize :: Type -> Int
typeSize (LitTy {})                 = Int
1
typeSize (TyVarTy {})               = Int
1
typeSize (AppTy Type
t1 Type
t2)              = Type -> Int
typeSize Type
t1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
typeSize Type
t2
typeSize (FunTy Type
t1 Type
t2)              = Type -> Int
typeSize Type
t1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
typeSize Type
t2
typeSize (ForAllTy (Bndr Id
tv ArgFlag
_) Type
t)   = Type -> Int
typeSize (Id -> Type
varType Id
tv) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
typeSize Type
t
typeSize (TyConApp TyCon
_ [Type]
ts)            = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Type -> Int) -> [Type] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Int
typeSize [Type]
ts)
typeSize (CastTy Type
ty Coercion
co)             = Type -> Int
typeSize Type
ty Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
typeSize (CoercionTy Coercion
co)            = Coercion -> Int
coercionSize Coercion
co

coercionSize :: Coercion -> Int
coercionSize :: Coercion -> Int
coercionSize (Refl Type
ty)             = Type -> Int
typeSize Type
ty
coercionSize (GRefl Role
_ Type
ty MCoercion
MRefl)    = Type -> Int
typeSize Type
ty
coercionSize (GRefl Role
_ Type
ty (MCo Coercion
co)) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
typeSize Type
ty Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
coercionSize (TyConAppCo Role
_ TyCon
_ [Coercion]
args) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Coercion -> Int) -> [Coercion] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Int
coercionSize [Coercion]
args)
coercionSize (AppCo Coercion
co Coercion
arg)      = Coercion -> Int
coercionSize Coercion
co Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
arg
coercionSize (ForAllCo Id
_ Coercion
h Coercion
co)   = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
h
coercionSize (FunCo Role
_ Coercion
co1 Coercion
co2)   = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co2
coercionSize (CoVarCo Id
_)         = Int
1
coercionSize (HoleCo CoercionHole
_)          = Int
1
coercionSize (AxiomInstCo CoAxiom Branched
_ Int
_ [Coercion]
args) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Coercion -> Int) -> [Coercion] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Int
coercionSize [Coercion]
args)
coercionSize (UnivCo UnivCoProvenance
p Role
_ Type
t1 Type
t2)  = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ UnivCoProvenance -> Int
provSize UnivCoProvenance
p Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
typeSize Type
t1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
typeSize Type
t2
coercionSize (SymCo Coercion
co)          = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
coercionSize (TransCo Coercion
co1 Coercion
co2)   = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co2
coercionSize (NthCo Role
_ Int
_ Coercion
co)      = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
coercionSize (LRCo  LeftOrRight
_ Coercion
co)        = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
coercionSize (InstCo Coercion
co Coercion
arg)     = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
arg
coercionSize (KindCo Coercion
co)         = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
coercionSize (SubCo Coercion
co)          = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
coercionSize (AxiomRuleCo CoAxiomRule
_ [Coercion]
cs)  = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Coercion -> Int) -> [Coercion] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Coercion -> Int
coercionSize [Coercion]
cs)

provSize :: UnivCoProvenance -> Int
provSize :: UnivCoProvenance -> Int
provSize UnivCoProvenance
UnsafeCoerceProv    = Int
1
provSize (PhantomProv Coercion
co)    = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
provSize (ProofIrrelProv Coercion
co) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Coercion -> Int
coercionSize Coercion
co
provSize (PluginProv String
_)      = Int
1