A Coercion is concrete evidence of the equality/convertibility of two types.
Moduleghc-9.10.3GHC2021
GHC.Core.Coercion
Module for (a) type kinds and (b) type coercions, as used in System FC. See Expr for more on System FC and how coercions fit into it.
- 21 types
- 179 values
- Packageghc-9.10.3
- Exports200
- LanguageGHC2021
- LicenceBSD-3-Clause
- SourceCoercion.hs
Main data type
19 declarationsA semantically more meaningful type to represent what may or may not be a useful Coercion.
Instances2Data, Outputable
Data MCoercionDefined in ghc-9.10.3 · GHC.Core.TyCo.RepOutputable MCoercionDefined in ghc-9.10.3 · GHC.Core.TyCo.Rep
Instances5Eq, Data, NFData, Outputable, Binary
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.
Instances2Data, Outputable
Data UnivCoProvenanceDefined in ghc-9.10.3 · GHC.Core.TyCo.RepOutputable UnivCoProvenanceDefined in ghc-9.10.3 · GHC.Core.TyCo.Rep
A coercion to be filled in by the type-checker. See Note [Coercion holes]
Constructors
Instances3Data, Outputable, Uniquable
Data CoercionHoleDefined in ghc-9.10.3 · GHC.Core.TyCo.RepOutputable CoercionHoleDefined in ghc-9.10.3 · GHC.Core.TyCo.RepUniquable CoercionHoleDefined in ghc-9.10.3 · GHC.Core.TyCo.Rep
Instances4Eq, Data, Outputable, Binary
Eq LeftOrRightDefined in ghc-9.10.3 · GHC.Types.BasicData LeftOrRightDefined in ghc-9.10.3 · GHC.Types.BasicOutputable LeftOrRightDefined in ghc-9.10.3 · GHC.Types.BasicBinary LeftOrRightDefined in ghc-9.10.3 · GHC.Types.Basic
Instances15Data, Ord, NamedThing, Outputable, Uniquable, HasOccName, …
Eq VarDefined in ghc-9.10.3 · GHC.Types.VarData VarDefined in ghc-9.10.3 · GHC.Types.VarOrd VarDefined in ghc-9.10.3 · GHC.Types.VarNamedThing VarDefined in ghc-9.10.3 · GHC.Types.VarOutputable VarDefined in ghc-9.10.3 · GHC.Types.VarUniquable VarDefined in ghc-9.10.3 · GHC.Types.VarOutputableBndr VarDefined in ghc-9.10.3 · GHC.Core.Ppr · orphanHasOccName VarDefined in ghc-9.10.3 · GHC.Types.VarModifyState IdDefined in ghc-9.10.3 · GHC.Iface.Ext.AstEq (DeBruijn CoreAlt)Defined in ghc-9.10.3 · GHC.Core.Map.Expr · orphanEq (DeBruijn CoreExpr)Defined in ghc-9.10.3 · GHC.Core.Map.Expr · orphanEq (DeBruijn Var)Defined in ghc-9.10.3 · GHC.Core.Map.TypeToHie (Context (Located Var))Defined in ghc-9.10.3 · GHC.Iface.Ext.AstOutputableBndr (Id, TagSig)Defined in ghc-9.10.3 · GHC.Stg.InferTags.TagSigtype Anno Id = SrcSpanAnnNDefined in ghc-9.10.3 · GHC.Hs.Extension · orphan
Coercion Variable
Type or Coercion Variable
See Note [Roles] in GHC.Core.Coercion
Order of constructors matters: the Ord instance coincides with the *super*typing relation on roles.
Instances7Eq, Data, Ord, Outputable, Binary, Anno, …
Eq RoleDefined in ghc-9.10.3 · Language.Haskell.Syntax.BasicData RoleDefined in ghc-9.10.3 · Language.Haskell.Syntax.BasicOrd RoleDefined in ghc-9.10.3 · Language.Haskell.Syntax.BasicOutputable RoleDefined in ghc-9.10.3 · GHC.Core.Coercion.Axiom · orphanBinary RoleDefined in ghc-9.10.3 · GHC.Core.Coercion.Axiom · orphantype Anno (Maybe Role) = EpAnnCODefined in ghc-9.10.3 · GHC.Hs.Decls · orphantype Anno (Maybe Role) = EpAnnCODefined in ghc-9.10.3 · GHC.Hs.Decls · orphan
Functions over coercions
Makes a coercion type from two types: the types whose equality is proven by the relevant Coercion
If it is the case that
c :: (t1 ~ t2)i.e. the kind of c relates t1 and t2, then coercionKind c = Pair t1 t2.
Apply coercionKind to multiple Coercions
Retrieve the role from a coercion.
Get a coercion's kind and role.
Constructing coercions
Make a generalized reflexive coercion
Make a reflexive coercion
Make a representational reflexive coercion
Make a nominal reflexive coercion
Return the left-hand type of the axiom, when the axiom is instantiated at the types given.
Instantiate the left-hand side of an unbranched axiom
Make a forall Coercion, where both types related by the coercion are quantified over the same variable.
Create a symmetric version of the given Coercion that asserts
equality between the same types but in the other "direction", so
a kind of t1 ~ t2 becomes the kind t2 ~ t1.
Extract the nth field of a FunCo
Instantiates a Coercion.
mkAppCo Apply a type constructor to a list of coercions. It is the caller's responsibility to get the roles correct on argument coercions.
Make a Coercion from a tycovar, a kind coercion, and a body coercion.
Make a Coercion quantified over a type/coercion variable; the variable has the same kind and visibility in both sides of the coercion
Make a phantom coercion between two types. The coercion passed in must be a nominal coercion between the kinds of the types.
Make a coercion from a coercion hole
mkUnivCo :: UnivCoProvenance-> Rolerole of the built coercion, "r"
-> Typet1 :: k1
-> Typet2 :: k2
-> Coercion:: t1 ~r t2
Make a universal coercion between two arbitrary types.
mkProofIrrelCo Make a "coercion between coercions".
Like downgradeRole_maybe, but panics if the change isn't a downgrade.
See Note [Role twiddling functions]
Given ty :: k1, co :: k1 ~ k2,
produces co' :: ty ~r (ty |> co)
Given r, ty :: k1, and co :: k1 ~N k2,
produces co' :: (ty |> co) ~r ty
Given ty :: k1, co :: k1 ~ k2, co2:: ty ~r ty',
produces @co' :: (ty |> co) ~r ty'
It is not only a utility function, but it saves allocation when co
is a GRefl coercion.
Given ty :: k1, co :: k1 ~ k2, co2:: ty' ~r ty,
produces @co' :: ty' ~r (ty |> co)
It is not only a utility function, but it saves allocation when co
is a GRefl coercion.
Given co :: (a :: k) ~ (b :: k') produce co' :: k ~ k'.
Creates a new coercion with both of its types casted by different casts
castCoercionKind g h1 h2, where g :: t1 ~r t2,
has type (t1 |> h1) ~r (t2 |> h2).
h1 and h2 must be nominal.
It calls coercionKindRole, so it's quite inefficient (which I stands for)
Use castCoercionKind2 instead if t1, t2, and r are known beforehand.
castCoercionKind1 g r t1 t2 h = coercionKind g r t1 t2 h h
That is, it's a specialised form of castCoercionKind, where the two
kind coercions are identical
castCoercionKind1 g r t1 t2 h, where g :: t1 ~r t2,
has type (t1 |> h) ~r (t2 |> h).
h must be nominal.
See Note [castCoercionKind1]
Creates a new coercion with both of its types casted by different casts
castCoercionKind2 g r t1 t2 h1 h2, where g :: t1 ~r t2,
has type (t1 |> h1) ~r (t2 |> h2).
h1 and h2 must be nominal.
Creates a primitive nominal type equality predicate. t1 ~# t2 Invariant: the types are not Coercions
Creates a primitive representational type equality predicate. t1 ~R# t2 Invariant: the types are not Coercions
Makes a lifted equality predicate at the given role
Creates a primitive nominal type equality predicate with an explicit (but homogeneous) kind: (~#) k k ty1 ty2
Decomposition
If `instNewTyCon_maybe T ts = Just (rep_ty, co)` then `co :: T ts ~R# rep_ty`
Checks for a newtype, and for being saturated
A function to check if we can reduce a type by one step. Used with topNormaliseTypeX.
The result of stepping in a normalisation function. See topNormaliseTypeX.
Constructors
NS_DoneNothing more to do
NS_AbortUtter failure. The outer function should fail too.
NS_Step RecTcChecker Type evWe stepped, yielding new bits; ^ ev is evidence; Usually a co :: old type ~ new type
Instances2Functor, Outputable
Functor NormaliseStepResultDefined in ghc-9.10.3 · GHC.Core.CoercionOutputable ev => Outputable (NormaliseStepResult ev)Defined in ghc-9.10.3 · GHC.Core.Coercion
Try one stepper and then try the next, if the first doesn't make progress. So if it returns NS_Done, it means that both steppers are satisfied
A NormaliseStepper that unwraps newtypes, careful not to fall into a loop. If it would fall into a loop, it produces NS_Abort.
Sometimes we want to look through a newtype and get its associated coercion.
This function strips off newtype layers enough to reveal something that isn't
a newtype. Specifically, here's the invariant:
topNormaliseNewType_maybe rec_nts ty = Just (co, ty')then (a) co : ty ~R ty'.
(b) ty' is not a newtype.
The function returns Nothing for non-newtypes,
or unsaturated applications
This function does *not* look through type families, because it has no access to the type family environment. If you do have that at hand, consider to use topNormaliseType_maybe, which should be a drop-in replacement for topNormaliseNewType_maybe If topNormliseNewType_maybe ty = Just (co, ty'), then co : ty ~R ty'
A general function for normalising the top-level of a type. It continues to use the provided NormaliseStepper until that function fails, and then this function returns. The roles of the coercions produced by the NormaliseStepper must all be the same, which is the role returned from the call to topNormaliseTypeX.
Typically ev is Coercion.
If topNormaliseTypeX step plus ty = Just (ev, ty')
then ty ~ev1~ t1 ~ev2~ t2 ... ~evn~ ty'
and ev = ev1 plus ev2 plus ... plus evn
If it returns Nothing then no newtype unwrapping could happen
Extract a covar, if possible. This check is dirty. Be ashamed of yourself. (It's dirty because it cares about the structure of a coercion, which is morally reprehensible.)
Attempt to take a coercion application apart.
Like splitForAllCo_maybe, but only returns Just for tyvar binder
Like splitForAllCo_maybe, but only returns Just for covar binder
Converts a coercion to be nominal, if possible. See Note [Role twiddling functions]
Tests if this coercion is obviously a generalized reflexive coercion. Guaranteed to work very quickly.
Tests if this coercion is obviously reflexive. Guaranteed to work very quickly. Sometimes a coercion can be reflexive, but not obviously so. c.f. isReflexiveCo
Returns the type coerced if this coercion is reflexive. Guaranteed to work very quickly. Sometimes a coercion can be reflexive, but not obviously so. c.f. isReflexiveCo_maybe
Returns the type coerced if this coercion is a generalized reflexive coercion. Guaranteed to work very quickly.
Slowly checks if the coercion is reflexive. Don't call this in a loop, as it walks over the entire coercion.
Extracts the coerced type from a reflexive coercion. This potentially walks over the entire coercion, so avoid doing this in a loop.
Tests if this MCoercion is obviously generalized reflexive Guaranteed to work very quickly.
Like mkCoherenceRightCo, but with an MCoercion
Compose two MCoercions via transitivity
Cast a type by an MCoercion
Get the reverse of an MCoercion
Coercion variables
Is this a coercion variable?
Satisfies isId v ==> isCoVar v == not (isNonCoVarId v).
Free variables
Get a deterministic set of the vars free in a coercion
Substitution
Substitute within a Coercion The substitution has to satisfy the invariants described in Note [The substitution invariant].
Substitute within several Coercions The substitution has to satisfy the invariants described in Note [The substitution invariant].
Coercion substitution, see zipTvSubst
Lifting
liftCoSubst role lc ty produces a coercion (at role role)
that coerces between lc_left(ty) and lc_right(ty), where
lc_left is a substitution mapping type variables to the left-hand
types of the mapped coercions in lc, and similar for lc_right.
extendLiftingContext :: LiftingContextoriginal LC
-> TyCoVarnew variable to map...
-> Coercion...to this lifted version
-> LiftingContext
Extend a lifting context with a new mapping.
extendLiftingContextAndInScope :: LiftingContextOriginal LC
-> TyCoVarnew variable to map...
-> Coercionto this coercion
-> LiftingContext
Extend a lifting context with a new mapping, and extend the in-scope set
liftCoSubstVarBndrUsing :: (r -> CoercionN)coercion getter
-> (LiftingContext -> Type -> r)callback
-> LiftingContext-> TyCoVar-> (LiftingContext, TyCoVar, r)
Is a var in the domain of a lifting context?
Extend the substitution component of a lifting context with a new binding for a coercion variable. Used during coercion optimisation.
Erase the environments in a lifting context
Like substForAllCoBndr, but works on a lifting context
Lookup a CoVar in the substitution in a LiftingContext
Get the InScopeSet from a LiftingContext
Instances1Outputable
Outputable LiftingContextDefined in ghc-9.10.3 · GHC.Core.Coercion
Apply "sym" to all coercions in a LiftCoEnv
Comparison
Syntactic equality of coercions
Compare two Coercions, with respect to an RnEnv2
Forcing evaluation of coercions
Pretty-printing
8 declarationsTidying
2 declarationsTidy a Coercion
See Note [Strictness in tidyType and friends]
Other
8 declarationslike mkKindCo, but aggressively & recursively optimizes to avoid using a KindCo constructor. The output role is nominal.
Assuming that two types are the same, ignoring coercions, find a nominal coercion between the types. This is useful when optimizing transitivity over coercion applications, where splitting two AppCos might yield different kinds. See Note [EtaAppCo] in GHC.Core.Coercion.Opt.
Given a coercion `co :: (t1 :: TYPE r1) ~ (t2 :: TYPE r2)` produce a coercion `rep_co :: r1 ~ r2` But actually it is possible that co :: (t1 :: CONSTRAINT r1) ~ (t2 :: CONSTRAINT r2) or co :: (t1 :: TYPE r1) ~ (t2 :: CONSTRAINT r2) or co :: (t1 :: CONSTRAINT r1) ~ (t2 :: TYPE r2) See Note [mkRuntimeRepCo]
Is there a hetero-kind coercion hole in this type? (That is, a coercion hole with ch_hetero_kind=True.) See wrinkle (EIK2) of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality
Is there a hetero-kind coercion hole in this coercion?
Set the type of a CoercionHole