{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
module GHC.Core.TyCo.Compare (
eqType, eqTypeX, eqTypes, nonDetCmpType, nonDetCmpTypes, nonDetCmpTypeX,
nonDetCmpTypesX, nonDetCmpTc,
eqVarBndrs,
pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,
tcEqTyConApps,
eqForAllVis, cmpForAllVis
) where
import GHC.Prelude
import GHC.Core.Type( typeKind, coreView, tcSplitAppTyNoView_maybe, splitAppTyNoView_maybe )
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.FVs
import GHC.Core.TyCon
import GHC.Types.Var
import GHC.Types.Unique
import GHC.Types.Var.Env
import GHC.Utils.Outputable
import GHC.Utils.Misc
import GHC.Utils.Panic
import GHC.Base (reallyUnsafePtrEquality#)
import qualified Data.Semigroup as S
tcEqKind :: HasDebugCallStack => Kind -> Kind -> Bool
tcEqKind :: HasDebugCallStack => Type -> Type -> Bool
tcEqKind = HasDebugCallStack => Type -> Type -> Bool
tcEqType
tcEqType :: HasDebugCallStack => Type -> Type -> Bool
tcEqType :: HasDebugCallStack => Type -> Type -> Bool
tcEqType Type
ty1 Type
ty2
= Type -> Type -> Bool
tcEqTypeNoSyns Type
ki1 Type
ki2
Bool -> Bool -> Bool
&& Type -> Type -> Bool
tcEqTypeNoSyns Type
ty1 Type
ty2
where
ki1 :: Type
ki1 = HasDebugCallStack => Type -> Type
typeKind Type
ty1
ki2 :: Type
ki2 = HasDebugCallStack => Type -> Type
typeKind Type
ty2
tcEqTypeNoKindCheck :: Type -> Type -> Bool
tcEqTypeNoKindCheck :: Type -> Type -> Bool
tcEqTypeNoKindCheck Type
ty1 Type
ty2
= Type -> Type -> Bool
tcEqTypeNoSyns Type
ty1 Type
ty2
tcEqTyConApps :: TyCon -> [Type] -> TyCon -> [Type] -> Bool
tcEqTyConApps :: TyCon -> [Type] -> TyCon -> [Type] -> Bool
tcEqTyConApps TyCon
tc1 [Type]
args1 TyCon
tc2 [Type]
args2
= TyCon
tc1 forall a. Eq a => a -> a -> Bool
== TyCon
tc2 Bool -> Bool -> Bool
&&
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> Type -> Bool
tcEqTypeNoKindCheck [Type]
args1 [Type]
args2)
tcEqTypeNoSyns :: Type -> Type -> Bool
tcEqTypeNoSyns :: Type -> Type -> Bool
tcEqTypeNoSyns Type
ta Type
tb = Bool -> Bool -> Type -> Type -> Bool
tc_eq_type Bool
False Bool
False Type
ta Type
tb
tcEqTypeVis :: Type -> Type -> Bool
tcEqTypeVis :: Type -> Type -> Bool
tcEqTypeVis Type
ty1 Type
ty2 = Bool -> Bool -> Type -> Type -> Bool
tc_eq_type Bool
False Bool
True Type
ty1 Type
ty2
pickyEqType :: Type -> Type -> Bool
pickyEqType :: Type -> Type -> Bool
pickyEqType Type
ty1 Type
ty2 = Bool -> Bool -> Type -> Type -> Bool
tc_eq_type Bool
True Bool
False Type
ty1 Type
ty2
tc_eq_type :: Bool
-> Bool
-> Type -> Type
-> Bool
tc_eq_type :: Bool -> Bool -> Type -> Type -> Bool
tc_eq_type Bool
keep_syns Bool
vis_only Type
orig_ty1 Type
orig_ty2
= RnEnv2 -> Type -> Type -> Bool
go RnEnv2
orig_env Type
orig_ty1 Type
orig_ty2
where
go :: RnEnv2 -> Type -> Type -> Bool
go :: RnEnv2 -> Type -> Type -> Bool
go RnEnv2
_ (TyConApp TyCon
tc1 []) (TyConApp TyCon
tc2 [])
| TyCon
tc1 forall a. Eq a => a -> a -> Bool
== TyCon
tc2
= Bool
True
go RnEnv2
env Type
t1 Type
t2 | Bool -> Bool
not Bool
keep_syns, Just Type
t1' <- Type -> Maybe Type
coreView Type
t1 = RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1' Type
t2
go RnEnv2
env Type
t1 Type
t2 | Bool -> Bool
not Bool
keep_syns, Just Type
t2' <- Type -> Maybe Type
coreView Type
t2 = RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1 Type
t2'
go RnEnv2
env (TyVarTy Var
tv1) (TyVarTy Var
tv2)
= RnEnv2 -> Var -> Var
rnOccL RnEnv2
env Var
tv1 forall a. Eq a => a -> a -> Bool
== RnEnv2 -> Var -> Var
rnOccR RnEnv2
env Var
tv2
go RnEnv2
_ (LitTy TyLit
lit1) (LitTy TyLit
lit2)
= TyLit
lit1 forall a. Eq a => a -> a -> Bool
== TyLit
lit2
go RnEnv2
env (ForAllTy (Bndr Var
tv1 ForAllTyFlag
vis1) Type
ty1)
(ForAllTy (Bndr Var
tv2 ForAllTyFlag
vis2) Type
ty2)
= ForAllTyFlag
vis1 ForAllTyFlag -> ForAllTyFlag -> Bool
`eqForAllVis` ForAllTyFlag
vis2
Bool -> Bool -> Bool
&& (Bool
vis_only Bool -> Bool -> Bool
|| RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env (Var -> Type
varType Var
tv1) (Var -> Type
varType Var
tv2))
Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
go (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
tv1 Var
tv2) Type
ty1 Type
ty2
go RnEnv2
env (FunTy FunTyFlag
_ Type
w1 Type
arg1 Type
res1) (FunTy FunTyFlag
_ Type
w2 Type
arg2 Type
res2)
= Bool
kinds_eq Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
arg1 Type
arg2 Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
res1 Type
res2 Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
w1 Type
w2
where
kinds_eq :: Bool
kinds_eq | Bool
vis_only = Bool
True
| Bool
otherwise = RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env (HasDebugCallStack => Type -> Type
typeKind Type
arg1) (HasDebugCallStack => Type -> Type
typeKind Type
arg2) Bool -> Bool -> Bool
&&
RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env (HasDebugCallStack => Type -> Type
typeKind Type
res1) (HasDebugCallStack => Type -> Type
typeKind Type
res2)
go RnEnv2
env (AppTy Type
s1 Type
t1) Type
ty2
| Just (Type
s2, Type
t2) <- Type -> Maybe (Type, Type)
tcSplitAppTyNoView_maybe Type
ty2
= RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
s1 Type
s2 Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
env Type
ty1 (AppTy Type
s2 Type
t2)
| Just (Type
s1, Type
t1) <- Type -> Maybe (Type, Type)
tcSplitAppTyNoView_maybe Type
ty1
= RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
s1 Type
s2 Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
env (TyConApp TyCon
tc1 [Type]
ts1) (TyConApp TyCon
tc2 [Type]
ts2)
= TyCon
tc1 forall a. Eq a => a -> a -> Bool
== TyCon
tc2 Bool -> Bool -> Bool
&& RnEnv2 -> [Bool] -> [Type] -> [Type] -> Bool
gos RnEnv2
env (TyCon -> [Bool]
tc_vis TyCon
tc1) [Type]
ts1 [Type]
ts2
go RnEnv2
env (CastTy Type
t1 KindCoercion
_) Type
t2 = RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
env Type
t1 (CastTy Type
t2 KindCoercion
_) = RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
_ (CoercionTy {}) (CoercionTy {}) = Bool
True
go RnEnv2
_ Type
_ Type
_ = Bool
False
gos :: RnEnv2 -> [Bool] -> [Type] -> [Type] -> Bool
gos RnEnv2
_ [Bool]
_ [] [] = Bool
True
gos RnEnv2
env (Bool
ig:[Bool]
igs) (Type
t1:[Type]
ts1) (Type
t2:[Type]
ts2) = (Bool
ig Bool -> Bool -> Bool
|| RnEnv2 -> Type -> Type -> Bool
go RnEnv2
env Type
t1 Type
t2)
Bool -> Bool -> Bool
&& RnEnv2 -> [Bool] -> [Type] -> [Type] -> Bool
gos RnEnv2
env [Bool]
igs [Type]
ts1 [Type]
ts2
gos RnEnv2
_ [Bool]
_ [Type]
_ [Type]
_ = Bool
False
tc_vis :: TyCon -> [Bool]
tc_vis :: TyCon -> [Bool]
tc_vis TyCon
tc | Bool
vis_only = [Bool]
inviss forall a. [a] -> [a] -> [a]
++ forall a. a -> [a]
repeat Bool
False
| Bool
otherwise = forall a. a -> [a]
repeat Bool
False
where
bndrs :: [TyConBinder]
bndrs = TyCon -> [TyConBinder]
tyConBinders TyCon
tc
inviss :: [Bool]
inviss = forall a b. (a -> b) -> [a] -> [b]
map forall tv. VarBndr tv TyConBndrVis -> Bool
isInvisibleTyConBinder [TyConBinder]
bndrs
orig_env :: RnEnv2
orig_env = InScopeSet -> RnEnv2
mkRnEnv2 forall a b. (a -> b) -> a -> b
$ VarSet -> InScopeSet
mkInScopeSet forall a b. (a -> b) -> a -> b
$ [Type] -> VarSet
tyCoVarsOfTypes [Type
orig_ty1, Type
orig_ty2]
{-# INLINE tc_eq_type #-}
eqForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Bool
eqForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Bool
eqForAllVis ForAllTyFlag
Required ForAllTyFlag
Required = Bool
True
eqForAllVis (Invisible Specificity
_) (Invisible Specificity
_) = Bool
True
eqForAllVis ForAllTyFlag
_ ForAllTyFlag
_ = Bool
False
cmpForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Ordering
cmpForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Ordering
cmpForAllVis ForAllTyFlag
Required ForAllTyFlag
Required = Ordering
EQ
cmpForAllVis ForAllTyFlag
Required (Invisible {}) = Ordering
LT
cmpForAllVis (Invisible Specificity
_) ForAllTyFlag
Required = Ordering
GT
cmpForAllVis (Invisible Specificity
_) (Invisible Specificity
_) = Ordering
EQ
eqType :: Type -> Type -> Bool
eqType :: Type -> Type -> Bool
eqType Type
t1 Type
t2 = Ordering -> Bool
isEqual forall a b. (a -> b) -> a -> b
$ Type -> Type -> Ordering
nonDetCmpType Type
t1 Type
t2
eqTypeX :: RnEnv2 -> Type -> Type -> Bool
eqTypeX :: RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2 = Ordering -> Bool
isEqual forall a b. (a -> b) -> a -> b
$ RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX RnEnv2
env Type
t1 Type
t2
eqTypes :: [Type] -> [Type] -> Bool
eqTypes :: [Type] -> [Type] -> Bool
eqTypes [Type]
tys1 [Type]
tys2 = Ordering -> Bool
isEqual forall a b. (a -> b) -> a -> b
$ [Type] -> [Type] -> Ordering
nonDetCmpTypes [Type]
tys1 [Type]
tys2
eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2
eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2
eqVarBndrs RnEnv2
env [] []
= forall a. a -> Maybe a
Just RnEnv2
env
eqVarBndrs RnEnv2
env (Var
tv1:[Var]
tvs1) (Var
tv2:[Var]
tvs2)
| RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env (Var -> Type
varType Var
tv1) (Var -> Type
varType Var
tv2)
= RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2
eqVarBndrs (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
tv1 Var
tv2) [Var]
tvs1 [Var]
tvs2
eqVarBndrs RnEnv2
_ [Var]
_ [Var]
_= forall a. Maybe a
Nothing
nonDetCmpType :: Type -> Type -> Ordering
nonDetCmpType :: Type -> Type -> Ordering
nonDetCmpType !Type
t1 !Type
t2
| Int#
1# <- forall a. a -> a -> Int#
reallyUnsafePtrEquality# Type
t1 Type
t2
= Ordering
EQ
nonDetCmpType (TyConApp TyCon
tc1 []) (TyConApp TyCon
tc2 []) | TyCon
tc1 forall a. Eq a => a -> a -> Bool
== TyCon
tc2
= Ordering
EQ
nonDetCmpType Type
t1 Type
t2
= RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX RnEnv2
rn_env Type
t1 Type
t2
where
rn_env :: RnEnv2
rn_env = InScopeSet -> RnEnv2
mkRnEnv2 (VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
tyCoVarsOfTypes [Type
t1, Type
t2]))
{-# INLINE nonDetCmpType #-}
nonDetCmpTypes :: [Type] -> [Type] -> Ordering
nonDetCmpTypes :: [Type] -> [Type] -> Ordering
nonDetCmpTypes [Type]
ts1 [Type]
ts2 = RnEnv2 -> [Type] -> [Type] -> Ordering
nonDetCmpTypesX RnEnv2
rn_env [Type]
ts1 [Type]
ts2
where
rn_env :: RnEnv2
rn_env = InScopeSet -> RnEnv2
mkRnEnv2 (VarSet -> InScopeSet
mkInScopeSet ([Type] -> VarSet
tyCoVarsOfTypes ([Type]
ts1 forall a. [a] -> [a] -> [a]
++ [Type]
ts2)))
data TypeOrdering = TLT
| TEQ
| TEQX
| TGT
deriving (TypeOrdering -> TypeOrdering -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TypeOrdering -> TypeOrdering -> Bool
$c/= :: TypeOrdering -> TypeOrdering -> Bool
== :: TypeOrdering -> TypeOrdering -> Bool
$c== :: TypeOrdering -> TypeOrdering -> Bool
Eq, Eq TypeOrdering
TypeOrdering -> TypeOrdering -> Bool
TypeOrdering -> TypeOrdering -> Ordering
TypeOrdering -> TypeOrdering -> TypeOrdering
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 :: TypeOrdering -> TypeOrdering -> TypeOrdering
$cmin :: TypeOrdering -> TypeOrdering -> TypeOrdering
max :: TypeOrdering -> TypeOrdering -> TypeOrdering
$cmax :: TypeOrdering -> TypeOrdering -> TypeOrdering
>= :: TypeOrdering -> TypeOrdering -> Bool
$c>= :: TypeOrdering -> TypeOrdering -> Bool
> :: TypeOrdering -> TypeOrdering -> Bool
$c> :: TypeOrdering -> TypeOrdering -> Bool
<= :: TypeOrdering -> TypeOrdering -> Bool
$c<= :: TypeOrdering -> TypeOrdering -> Bool
< :: TypeOrdering -> TypeOrdering -> Bool
$c< :: TypeOrdering -> TypeOrdering -> Bool
compare :: TypeOrdering -> TypeOrdering -> Ordering
$ccompare :: TypeOrdering -> TypeOrdering -> Ordering
Ord, Int -> TypeOrdering
TypeOrdering -> Int
TypeOrdering -> [TypeOrdering]
TypeOrdering -> TypeOrdering
TypeOrdering -> TypeOrdering -> [TypeOrdering]
TypeOrdering -> TypeOrdering -> TypeOrdering -> [TypeOrdering]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: TypeOrdering -> TypeOrdering -> TypeOrdering -> [TypeOrdering]
$cenumFromThenTo :: TypeOrdering -> TypeOrdering -> TypeOrdering -> [TypeOrdering]
enumFromTo :: TypeOrdering -> TypeOrdering -> [TypeOrdering]
$cenumFromTo :: TypeOrdering -> TypeOrdering -> [TypeOrdering]
enumFromThen :: TypeOrdering -> TypeOrdering -> [TypeOrdering]
$cenumFromThen :: TypeOrdering -> TypeOrdering -> [TypeOrdering]
enumFrom :: TypeOrdering -> [TypeOrdering]
$cenumFrom :: TypeOrdering -> [TypeOrdering]
fromEnum :: TypeOrdering -> Int
$cfromEnum :: TypeOrdering -> Int
toEnum :: Int -> TypeOrdering
$ctoEnum :: Int -> TypeOrdering
pred :: TypeOrdering -> TypeOrdering
$cpred :: TypeOrdering -> TypeOrdering
succ :: TypeOrdering -> TypeOrdering
$csucc :: TypeOrdering -> TypeOrdering
Enum, TypeOrdering
forall a. a -> a -> Bounded a
maxBound :: TypeOrdering
$cmaxBound :: TypeOrdering
minBound :: TypeOrdering
$cminBound :: TypeOrdering
Bounded)
nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX RnEnv2
env Type
orig_t1 Type
orig_t2 =
case RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
orig_t1 Type
orig_t2 of
TypeOrdering
TEQX -> TypeOrdering -> Ordering
toOrdering forall a b. (a -> b) -> a -> b
$ RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
k1 Type
k2
TypeOrdering
ty_ordering -> TypeOrdering -> Ordering
toOrdering TypeOrdering
ty_ordering
where
k1 :: Type
k1 = HasDebugCallStack => Type -> Type
typeKind Type
orig_t1
k2 :: Type
k2 = HasDebugCallStack => Type -> Type
typeKind Type
orig_t2
toOrdering :: TypeOrdering -> Ordering
toOrdering :: TypeOrdering -> Ordering
toOrdering TypeOrdering
TLT = Ordering
LT
toOrdering TypeOrdering
TEQ = Ordering
EQ
toOrdering TypeOrdering
TEQX = Ordering
EQ
toOrdering TypeOrdering
TGT = Ordering
GT
liftOrdering :: Ordering -> TypeOrdering
liftOrdering :: Ordering -> TypeOrdering
liftOrdering Ordering
LT = TypeOrdering
TLT
liftOrdering Ordering
EQ = TypeOrdering
TEQ
liftOrdering Ordering
GT = TypeOrdering
TGT
thenCmpTy :: TypeOrdering -> TypeOrdering -> TypeOrdering
thenCmpTy :: TypeOrdering -> TypeOrdering -> TypeOrdering
thenCmpTy TypeOrdering
TEQ TypeOrdering
rel = TypeOrdering
rel
thenCmpTy TypeOrdering
TEQX TypeOrdering
rel = TypeOrdering -> TypeOrdering
hasCast TypeOrdering
rel
thenCmpTy TypeOrdering
rel TypeOrdering
_ = TypeOrdering
rel
hasCast :: TypeOrdering -> TypeOrdering
hasCast :: TypeOrdering -> TypeOrdering
hasCast TypeOrdering
TEQ = TypeOrdering
TEQX
hasCast TypeOrdering
rel = TypeOrdering
rel
go :: RnEnv2 -> Type -> Type -> TypeOrdering
go :: RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
_ (TyConApp TyCon
tc1 []) (TyConApp TyCon
tc2 [])
| TyCon
tc1 forall a. Eq a => a -> a -> Bool
== TyCon
tc2
= TypeOrdering
TEQ
go RnEnv2
env Type
t1 Type
t2
| Just Type
t1' <- Type -> Maybe Type
coreView Type
t1 = RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
t1' Type
t2
| Just Type
t2' <- Type -> Maybe Type
coreView Type
t2 = RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
t1 Type
t2'
go RnEnv2
env (TyVarTy Var
tv1) (TyVarTy Var
tv2)
= Ordering -> TypeOrdering
liftOrdering forall a b. (a -> b) -> a -> b
$ RnEnv2 -> Var -> Var
rnOccL RnEnv2
env Var
tv1 Var -> Var -> Ordering
`nonDetCmpVar` RnEnv2 -> Var -> Var
rnOccR RnEnv2
env Var
tv2
go RnEnv2
env (ForAllTy (Bndr Var
tv1 ForAllTyFlag
vis1) Type
t1) (ForAllTy (Bndr Var
tv2 ForAllTyFlag
vis2) Type
t2)
= Ordering -> TypeOrdering
liftOrdering (ForAllTyFlag
vis1 ForAllTyFlag -> ForAllTyFlag -> Ordering
`cmpForAllVis` ForAllTyFlag
vis2)
TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env (Var -> Type
varType Var
tv1) (Var -> Type
varType Var
tv2)
TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> Type -> Type -> TypeOrdering
go (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
tv1 Var
tv2) Type
t1 Type
t2
go RnEnv2
env (AppTy Type
s1 Type
t1) Type
ty2
| Just (Type
s2, Type
t2) <- HasDebugCallStack => Type -> Maybe (Type, Type)
splitAppTyNoView_maybe Type
ty2
= RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
s1 Type
s2 TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
env Type
ty1 (AppTy Type
s2 Type
t2)
| Just (Type
s1, Type
t1) <- HasDebugCallStack => Type -> Maybe (Type, Type)
splitAppTyNoView_maybe Type
ty1
= RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
s1 Type
s2 TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
env (FunTy FunTyFlag
_ Type
w1 Type
s1 Type
t1) (FunTy FunTyFlag
_ Type
w2 Type
s2 Type
t2)
= Ordering -> TypeOrdering
liftOrdering (RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX RnEnv2
env Type
s1 Type
s2 forall a. Semigroup a => a -> a -> a
S.<> RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX RnEnv2
env Type
t1 Type
t2)
TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
w1 Type
w2
go RnEnv2
env (TyConApp TyCon
tc1 [Type]
tys1) (TyConApp TyCon
tc2 [Type]
tys2)
= Ordering -> TypeOrdering
liftOrdering (TyCon
tc1 TyCon -> TyCon -> Ordering
`nonDetCmpTc` TyCon
tc2) TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> [Type] -> [Type] -> TypeOrdering
gos RnEnv2
env [Type]
tys1 [Type]
tys2
go RnEnv2
_ (LitTy TyLit
l1) (LitTy TyLit
l2) = Ordering -> TypeOrdering
liftOrdering (TyLit -> TyLit -> Ordering
nonDetCmpTyLit TyLit
l1 TyLit
l2)
go RnEnv2
env (CastTy Type
t1 KindCoercion
_) Type
t2 = TypeOrdering -> TypeOrdering
hasCast forall a b. (a -> b) -> a -> b
$ RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
env Type
t1 (CastTy Type
t2 KindCoercion
_) = TypeOrdering -> TypeOrdering
hasCast forall a b. (a -> b) -> a -> b
$ RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
t1 Type
t2
go RnEnv2
_ (CoercionTy {}) (CoercionTy {}) = TypeOrdering
TEQ
go RnEnv2
_ Type
ty1 Type
ty2
= Ordering -> TypeOrdering
liftOrdering forall a b. (a -> b) -> a -> b
$ (Type -> Int
get_rank Type
ty1) forall a. Ord a => a -> a -> Ordering
`compare` (Type -> Int
get_rank Type
ty2)
where get_rank :: Type -> Int
get_rank :: Type -> Int
get_rank (CastTy {})
= forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"nonDetCmpTypeX.get_rank" (forall a. Outputable a => a -> SDoc
ppr [Type
ty1,Type
ty2])
get_rank (TyVarTy {}) = Int
0
get_rank (CoercionTy {}) = Int
1
get_rank (AppTy {}) = Int
3
get_rank (LitTy {}) = Int
4
get_rank (TyConApp {}) = Int
5
get_rank (FunTy {}) = Int
6
get_rank (ForAllTy {}) = Int
7
gos :: RnEnv2 -> [Type] -> [Type] -> TypeOrdering
gos :: RnEnv2 -> [Type] -> [Type] -> TypeOrdering
gos RnEnv2
_ [] [] = TypeOrdering
TEQ
gos RnEnv2
_ [] [Type]
_ = TypeOrdering
TLT
gos RnEnv2
_ [Type]
_ [] = TypeOrdering
TGT
gos RnEnv2
env (Type
ty1:[Type]
tys1) (Type
ty2:[Type]
tys2) = RnEnv2 -> Type -> Type -> TypeOrdering
go RnEnv2
env Type
ty1 Type
ty2 TypeOrdering -> TypeOrdering -> TypeOrdering
`thenCmpTy` RnEnv2 -> [Type] -> [Type] -> TypeOrdering
gos RnEnv2
env [Type]
tys1 [Type]
tys2
nonDetCmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering
nonDetCmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering
nonDetCmpTypesX RnEnv2
_ [] [] = Ordering
EQ
nonDetCmpTypesX RnEnv2
env (Type
t1:[Type]
tys1) (Type
t2:[Type]
tys2) = RnEnv2 -> Type -> Type -> Ordering
nonDetCmpTypeX RnEnv2
env Type
t1 Type
t2 forall a. Semigroup a => a -> a -> a
S.<>
RnEnv2 -> [Type] -> [Type] -> Ordering
nonDetCmpTypesX RnEnv2
env [Type]
tys1 [Type]
tys2
nonDetCmpTypesX RnEnv2
_ [] [Type]
_ = Ordering
LT
nonDetCmpTypesX RnEnv2
_ [Type]
_ [] = Ordering
GT
nonDetCmpTc :: TyCon -> TyCon -> Ordering
nonDetCmpTc :: TyCon -> TyCon -> Ordering
nonDetCmpTc TyCon
tc1 TyCon
tc2
= Unique
u1 Unique -> Unique -> Ordering
`nonDetCmpUnique` Unique
u2
where
u1 :: Unique
u1 = TyCon -> Unique
tyConUnique TyCon
tc1
u2 :: Unique
u2 = TyCon -> Unique
tyConUnique TyCon
tc2