{-# LANGUAGE CPP #-}
module FunDeps (
FunDepEqn(..), pprEquation,
improveFromInstEnv, improveFromAnother,
checkInstCoverage, checkFunDeps,
pprFundeps
) where
#include "HsVersions.h"
import GhcPrelude
import Name
import Var
import Class
import Predicate
import Type
import TcType( transSuperClasses )
import CoAxiom( TypeEqn )
import Unify
import InstEnv
import VarSet
import VarEnv
import TyCoFVs
import TyCoPpr( pprWithExplicitKindsWhen )
import FV
import Outputable
import ErrUtils( Validity(..), allValid )
import SrcLoc
import Util
import Pair ( Pair(..) )
import Data.List ( nubBy )
import Data.Maybe
import Data.Foldable ( fold )
data FunDepEqn loc
= FDEqn { FunDepEqn loc -> [TyVar]
fd_qtvs :: [TyVar]
, FunDepEqn loc -> [TypeEqn]
fd_eqs :: [TypeEqn]
, FunDepEqn loc -> PredType
fd_pred1 :: PredType
, FunDepEqn loc -> PredType
fd_pred2 :: PredType
, FunDepEqn loc -> loc
fd_loc :: loc }
instFD :: FunDep TyVar -> [TyVar] -> [Type] -> FunDep Type
instFD :: FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD ([TyVar]
ls,[TyVar]
rs) [TyVar]
tvs [PredType]
tys
= ((TyVar -> PredType) -> [TyVar] -> [PredType]
forall a b. (a -> b) -> [a] -> [b]
map TyVar -> PredType
lookup [TyVar]
ls, (TyVar -> PredType) -> [TyVar] -> [PredType]
forall a b. (a -> b) -> [a] -> [b]
map TyVar -> PredType
lookup [TyVar]
rs)
where
env :: VarEnv PredType
env = [TyVar] -> [PredType] -> VarEnv PredType
forall a. [TyVar] -> [a] -> VarEnv a
zipVarEnv [TyVar]
tvs [PredType]
tys
lookup :: TyVar -> PredType
lookup TyVar
tv = VarEnv PredType -> TyVar -> PredType
forall a. VarEnv a -> TyVar -> a
lookupVarEnv_NF VarEnv PredType
env TyVar
tv
zipAndComputeFDEqs :: (Type -> Type -> Bool)
-> [Type] -> [Type]
-> [TypeEqn]
zipAndComputeFDEqs :: (PredType -> PredType -> Bool)
-> [PredType] -> [PredType] -> [TypeEqn]
zipAndComputeFDEqs PredType -> PredType -> Bool
discard (PredType
ty1:[PredType]
tys1) (PredType
ty2:[PredType]
tys2)
| PredType -> PredType -> Bool
discard PredType
ty1 PredType
ty2 = (PredType -> PredType -> Bool)
-> [PredType] -> [PredType] -> [TypeEqn]
zipAndComputeFDEqs PredType -> PredType -> Bool
discard [PredType]
tys1 [PredType]
tys2
| Bool
otherwise = PredType -> PredType -> TypeEqn
forall a. a -> a -> Pair a
Pair PredType
ty1 PredType
ty2 TypeEqn -> [TypeEqn] -> [TypeEqn]
forall a. a -> [a] -> [a]
: (PredType -> PredType -> Bool)
-> [PredType] -> [PredType] -> [TypeEqn]
zipAndComputeFDEqs PredType -> PredType -> Bool
discard [PredType]
tys1 [PredType]
tys2
zipAndComputeFDEqs PredType -> PredType -> Bool
_ [PredType]
_ [PredType]
_ = []
improveFromAnother :: loc
-> PredType
-> PredType
-> [FunDepEqn loc]
improveFromAnother :: loc -> PredType -> PredType -> [FunDepEqn loc]
improveFromAnother loc
loc PredType
pred1 PredType
pred2
| Just (Class
cls1, [PredType]
tys1) <- PredType -> Maybe (Class, [PredType])
getClassPredTys_maybe PredType
pred1
, Just (Class
cls2, [PredType]
tys2) <- PredType -> Maybe (Class, [PredType])
getClassPredTys_maybe PredType
pred2
, Class
cls1 Class -> Class -> Bool
forall a. Eq a => a -> a -> Bool
== Class
cls2
= [ FDEqn :: forall loc.
[TyVar]
-> [TypeEqn] -> PredType -> PredType -> loc -> FunDepEqn loc
FDEqn { fd_qtvs :: [TyVar]
fd_qtvs = [], fd_eqs :: [TypeEqn]
fd_eqs = [TypeEqn]
eqs, fd_pred1 :: PredType
fd_pred1 = PredType
pred1, fd_pred2 :: PredType
fd_pred2 = PredType
pred2, fd_loc :: loc
fd_loc = loc
loc }
| let ([TyVar]
cls_tvs, [FunDep TyVar]
cls_fds) = Class -> ([TyVar], [FunDep TyVar])
classTvsFds Class
cls1
, FunDep TyVar
fd <- [FunDep TyVar]
cls_fds
, let ([PredType]
ltys1, [PredType]
rs1) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
cls_tvs [PredType]
tys1
([PredType]
ltys2, [PredType]
rs2) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
cls_tvs [PredType]
tys2
, [PredType] -> [PredType] -> Bool
eqTypes [PredType]
ltys1 [PredType]
ltys2
, let eqs :: [TypeEqn]
eqs = (PredType -> PredType -> Bool)
-> [PredType] -> [PredType] -> [TypeEqn]
zipAndComputeFDEqs PredType -> PredType -> Bool
eqType [PredType]
rs1 [PredType]
rs2
, Bool -> Bool
not ([TypeEqn] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TypeEqn]
eqs) ]
improveFromAnother loc
_ PredType
_ PredType
_ = []
instance Outputable (FunDepEqn a) where
ppr :: FunDepEqn a -> SDoc
ppr = FunDepEqn a -> SDoc
forall a. FunDepEqn a -> SDoc
pprEquation
pprEquation :: FunDepEqn a -> SDoc
pprEquation :: FunDepEqn a -> SDoc
pprEquation (FDEqn { fd_qtvs :: forall loc. FunDepEqn loc -> [TyVar]
fd_qtvs = [TyVar]
qtvs, fd_eqs :: forall loc. FunDepEqn loc -> [TypeEqn]
fd_eqs = [TypeEqn]
pairs })
= [SDoc] -> SDoc
vcat [String -> SDoc
text String
"forall" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
braces ((TyVar -> SDoc) -> [TyVar] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVar]
qtvs),
Int -> SDoc -> SDoc
nest Int
2 ([SDoc] -> SDoc
vcat [ PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
t1 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"~" SDoc -> SDoc -> SDoc
<+> PredType -> SDoc
forall a. Outputable a => a -> SDoc
ppr PredType
t2
| Pair PredType
t1 PredType
t2 <- [TypeEqn]
pairs])]
improveFromInstEnv :: InstEnvs
-> (PredType -> SrcSpan -> loc)
-> PredType
-> [FunDepEqn loc]
improveFromInstEnv :: InstEnvs
-> (PredType -> SrcSpan -> loc) -> PredType -> [FunDepEqn loc]
improveFromInstEnv InstEnvs
inst_env PredType -> SrcSpan -> loc
mk_loc PredType
pred
| Just (Class
cls, [PredType]
tys) <- ASSERT2( isClassPred pred, ppr pred )
PredType -> Maybe (Class, [PredType])
getClassPredTys_maybe PredType
pred
, let ([TyVar]
cls_tvs, [FunDep TyVar]
cls_fds) = Class -> ([TyVar], [FunDep TyVar])
classTvsFds Class
cls
instances :: [ClsInst]
instances = InstEnvs -> Class -> [ClsInst]
classInstances InstEnvs
inst_env Class
cls
rough_tcs :: [Maybe Name]
rough_tcs = [PredType] -> [Maybe Name]
roughMatchTcs [PredType]
tys
= [ FDEqn :: forall loc.
[TyVar]
-> [TypeEqn] -> PredType -> PredType -> loc -> FunDepEqn loc
FDEqn { fd_qtvs :: [TyVar]
fd_qtvs = [TyVar]
meta_tvs, fd_eqs :: [TypeEqn]
fd_eqs = [TypeEqn]
eqs
, fd_pred1 :: PredType
fd_pred1 = PredType
p_inst, fd_pred2 :: PredType
fd_pred2 = PredType
pred
, fd_loc :: loc
fd_loc = PredType -> SrcSpan -> loc
mk_loc PredType
p_inst (TyVar -> SrcSpan
forall a. NamedThing a => a -> SrcSpan
getSrcSpan (ClsInst -> TyVar
is_dfun ClsInst
ispec)) }
| FunDep TyVar
fd <- [FunDep TyVar]
cls_fds
, let trimmed_tcs :: [Maybe Name]
trimmed_tcs = [TyVar] -> FunDep TyVar -> [Maybe Name] -> [Maybe Name]
trimRoughMatchTcs [TyVar]
cls_tvs FunDep TyVar
fd [Maybe Name]
rough_tcs
, ClsInst
ispec <- [ClsInst]
instances
, ([TyVar]
meta_tvs, [TypeEqn]
eqs) <- [TyVar]
-> FunDep TyVar
-> ClsInst
-> [PredType]
-> [Maybe Name]
-> [([TyVar], [TypeEqn])]
improveClsFD [TyVar]
cls_tvs FunDep TyVar
fd ClsInst
ispec
[PredType]
tys [Maybe Name]
trimmed_tcs
, let p_inst :: PredType
p_inst = Class -> [PredType] -> PredType
mkClassPred Class
cls (ClsInst -> [PredType]
is_tys ClsInst
ispec)
]
improveFromInstEnv InstEnvs
_ PredType -> SrcSpan -> loc
_ PredType
_ = []
improveClsFD :: [TyVar] -> FunDep TyVar
-> ClsInst
-> [Type] -> [Maybe Name]
-> [([TyCoVar], [TypeEqn])]
improveClsFD :: [TyVar]
-> FunDep TyVar
-> ClsInst
-> [PredType]
-> [Maybe Name]
-> [([TyVar], [TypeEqn])]
improveClsFD [TyVar]
clas_tvs FunDep TyVar
fd
(ClsInst { is_tvs :: ClsInst -> [TyVar]
is_tvs = [TyVar]
qtvs, is_tys :: ClsInst -> [PredType]
is_tys = [PredType]
tys_inst, is_tcs :: ClsInst -> [Maybe Name]
is_tcs = [Maybe Name]
rough_tcs_inst })
[PredType]
tys_actual [Maybe Name]
rough_tcs_actual
| [Maybe Name] -> [Maybe Name] -> Bool
instanceCantMatch [Maybe Name]
rough_tcs_inst [Maybe Name]
rough_tcs_actual
= []
| Bool
otherwise
= ASSERT2( equalLength tys_inst tys_actual &&
equalLength tys_inst clas_tvs
, ppr tys_inst <+> ppr tys_actual )
case [PredType] -> [PredType] -> Maybe TCvSubst
tcMatchTyKis [PredType]
ltys1 [PredType]
ltys2 of
Maybe TCvSubst
Nothing -> []
Just TCvSubst
subst | Maybe TCvSubst -> Bool
forall a. Maybe a -> Bool
isJust (TCvSubst -> [PredType] -> [PredType] -> Maybe TCvSubst
tcMatchTyKisX TCvSubst
subst [PredType]
rtys1 [PredType]
rtys2)
-> []
| [TypeEqn] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TypeEqn]
fdeqs
-> []
| Bool
otherwise
->
[([TyVar]
meta_tvs, [TypeEqn]
fdeqs)]
where
rtys1' :: [PredType]
rtys1' = (PredType -> PredType) -> [PredType] -> [PredType]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> PredType -> PredType
substTyUnchecked TCvSubst
subst) [PredType]
rtys1
fdeqs :: [TypeEqn]
fdeqs = (PredType -> PredType -> Bool)
-> [PredType] -> [PredType] -> [TypeEqn]
zipAndComputeFDEqs (\PredType
_ PredType
_ -> Bool
False) [PredType]
rtys1' [PredType]
rtys2
meta_tvs :: [TyVar]
meta_tvs = [ TyVar -> PredType -> TyVar
setVarType TyVar
tv (TCvSubst -> PredType -> PredType
substTyUnchecked TCvSubst
subst (TyVar -> PredType
varType TyVar
tv))
| TyVar
tv <- [TyVar]
qtvs, TyVar
tv TyVar -> TCvSubst -> Bool
`notElemTCvSubst` TCvSubst
subst ]
where
([PredType]
ltys1, [PredType]
rtys1) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
clas_tvs [PredType]
tys_inst
([PredType]
ltys2, [PredType]
rtys2) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
clas_tvs [PredType]
tys_actual
checkInstCoverage :: Bool
-> Class -> [PredType] -> [Type]
-> Validity
checkInstCoverage :: Bool -> Class -> [PredType] -> [PredType] -> Validity
checkInstCoverage Bool
be_liberal Class
clas [PredType]
theta [PredType]
inst_taus
= [Validity] -> Validity
allValid ((FunDep TyVar -> Validity) -> [FunDep TyVar] -> [Validity]
forall a b. (a -> b) -> [a] -> [b]
map FunDep TyVar -> Validity
fundep_ok [FunDep TyVar]
fds)
where
([TyVar]
tyvars, [FunDep TyVar]
fds) = Class -> ([TyVar], [FunDep TyVar])
classTvsFds Class
clas
fundep_ok :: FunDep TyVar -> Validity
fundep_ok FunDep TyVar
fd
| Pair Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (VarSet -> Bool
isEmptyVarSet (VarSet -> Bool) -> Pair VarSet -> Pair Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair VarSet
undetermined_tvs) = Validity
IsValid
| Bool
otherwise = SDoc -> Validity
NotValid SDoc
msg
where
([PredType]
ls,[PredType]
rs) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
tyvars [PredType]
inst_taus
ls_tvs :: VarSet
ls_tvs = [PredType] -> VarSet
tyCoVarsOfTypes [PredType]
ls
rs_tvs :: Pair VarSet
rs_tvs = [PredType] -> Pair VarSet
splitVisVarsOfTypes [PredType]
rs
undetermined_tvs :: Pair VarSet
undetermined_tvs | Bool
be_liberal = Pair VarSet
liberal_undet_tvs
| Bool
otherwise = Pair VarSet
conserv_undet_tvs
closed_ls_tvs :: VarSet
closed_ls_tvs = [PredType] -> VarSet -> VarSet
oclose [PredType]
theta VarSet
ls_tvs
liberal_undet_tvs :: Pair VarSet
liberal_undet_tvs = (VarSet -> VarSet -> VarSet
`minusVarSet` VarSet
closed_ls_tvs) (VarSet -> VarSet) -> Pair VarSet -> Pair VarSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair VarSet
rs_tvs
conserv_undet_tvs :: Pair VarSet
conserv_undet_tvs = (VarSet -> VarSet -> VarSet
`minusVarSet` VarSet
ls_tvs) (VarSet -> VarSet) -> Pair VarSet -> Pair VarSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair VarSet
rs_tvs
undet_set :: VarSet
undet_set = Pair VarSet -> VarSet
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold Pair VarSet
undetermined_tvs
msg :: SDoc
msg = Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen
(VarSet -> Bool
isEmptyVarSet (VarSet -> Bool) -> VarSet -> Bool
forall a b. (a -> b) -> a -> b
$ Pair VarSet -> VarSet
forall a. Pair a -> a
pSnd Pair VarSet
undetermined_tvs) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [
[SDoc] -> SDoc
sep [ String -> SDoc
text String
"The"
SDoc -> SDoc -> SDoc
<+> Bool -> SDoc -> SDoc
ppWhen Bool
be_liberal (String -> SDoc
text String
"liberal")
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"coverage condition fails in class"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
clas)
, Int -> SDoc -> SDoc
nest Int
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text String
"for functional dependency:"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (FunDep TyVar -> SDoc
forall a. Outputable a => FunDep a -> SDoc
pprFunDep FunDep TyVar
fd) ]
, [SDoc] -> SDoc
sep [ String -> SDoc
text String
"Reason: lhs type"SDoc -> SDoc -> SDoc
<>[PredType] -> SDoc
forall a. [a] -> SDoc
plural [PredType]
ls SDoc -> SDoc -> SDoc
<+> [PredType] -> SDoc
forall a. Outputable a => [a] -> SDoc
pprQuotedList [PredType]
ls
, Int -> SDoc -> SDoc
nest Int
2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
(if [PredType] -> Bool
forall a. [a] -> Bool
isSingleton [PredType]
ls
then String -> SDoc
text String
"does not"
else String -> SDoc
text String
"do not jointly")
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"determine rhs type"SDoc -> SDoc -> SDoc
<>[PredType] -> SDoc
forall a. [a] -> SDoc
plural [PredType]
rs
SDoc -> SDoc -> SDoc
<+> [PredType] -> SDoc
forall a. Outputable a => [a] -> SDoc
pprQuotedList [PredType]
rs ]
, String -> SDoc
text String
"Un-determined variable" SDoc -> SDoc -> SDoc
<> VarSet -> SDoc
pluralVarSet VarSet
undet_set SDoc -> SDoc -> SDoc
<> SDoc
colon
SDoc -> SDoc -> SDoc
<+> VarSet -> ([TyVar] -> SDoc) -> SDoc
pprVarSet VarSet
undet_set ((TyVar -> SDoc) -> [TyVar] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas TyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr)
, Bool -> SDoc -> SDoc
ppWhen (Bool -> Bool
not Bool
be_liberal Bool -> Bool -> Bool
&&
Pair Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (VarSet -> Bool
isEmptyVarSet (VarSet -> Bool) -> Pair VarSet -> Pair Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair VarSet
liberal_undet_tvs)) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
String -> SDoc
text String
"Using UndecidableInstances might help" ]
oclose :: [PredType] -> TyCoVarSet -> TyCoVarSet
oclose :: [PredType] -> VarSet -> VarSet
oclose [PredType]
preds VarSet
fixed_tvs
| [(VarSet, VarSet)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(VarSet, VarSet)]
tv_fds = VarSet
fixed_tvs
| Bool
otherwise = (VarSet -> VarSet) -> VarSet -> VarSet
fixVarSet VarSet -> VarSet
extend VarSet
fixed_tvs
where
extend :: VarSet -> VarSet
extend VarSet
fixed_tvs = (VarSet -> (VarSet, VarSet) -> VarSet)
-> VarSet -> [(VarSet, VarSet)] -> VarSet
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' VarSet -> (VarSet, VarSet) -> VarSet
add VarSet
fixed_tvs [(VarSet, VarSet)]
tv_fds
where
add :: VarSet -> (VarSet, VarSet) -> VarSet
add VarSet
fixed_tvs (VarSet
ls,VarSet
rs)
| VarSet
ls VarSet -> VarSet -> Bool
`subVarSet` VarSet
fixed_tvs = VarSet
fixed_tvs VarSet -> VarSet -> VarSet
`unionVarSet` VarSet -> VarSet
closeOverKinds VarSet
rs
| Bool
otherwise = VarSet
fixed_tvs
tv_fds :: [(TyCoVarSet,TyCoVarSet)]
tv_fds :: [(VarSet, VarSet)]
tv_fds = [ ([PredType] -> VarSet
tyCoVarsOfTypes [PredType]
ls, FV -> VarSet
fvVarSet (FV -> VarSet) -> FV -> VarSet
forall a b. (a -> b) -> a -> b
$ Bool -> [PredType] -> FV
injectiveVarsOfTypes Bool
True [PredType]
rs)
| PredType
pred <- [PredType]
preds
, PredType
pred' <- PredType
pred PredType -> [PredType] -> [PredType]
forall a. a -> [a] -> [a]
: PredType -> [PredType]
transSuperClasses PredType
pred
, ([PredType]
ls, [PredType]
rs) <- PredType -> [FunDep PredType]
determined PredType
pred' ]
determined :: PredType -> [([Type],[Type])]
determined :: PredType -> [FunDep PredType]
determined PredType
pred
= case PredType -> Pred
classifyPredType PredType
pred of
EqPred EqRel
NomEq PredType
t1 PredType
t2 -> [([PredType
t1],[PredType
t2]), ([PredType
t2],[PredType
t1])]
ClassPred Class
cls [PredType]
tys -> [ FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
cls_tvs [PredType]
tys
| let ([TyVar]
cls_tvs, [FunDep TyVar]
cls_fds) = Class -> ([TyVar], [FunDep TyVar])
classTvsFds Class
cls
, FunDep TyVar
fd <- [FunDep TyVar]
cls_fds ]
Pred
_ -> []
checkFunDeps :: InstEnvs -> ClsInst -> [ClsInst]
checkFunDeps :: InstEnvs -> ClsInst -> [ClsInst]
checkFunDeps InstEnvs
inst_envs (ClsInst { is_tvs :: ClsInst -> [TyVar]
is_tvs = [TyVar]
qtvs1, is_cls :: ClsInst -> Class
is_cls = Class
cls
, is_tys :: ClsInst -> [PredType]
is_tys = [PredType]
tys1, is_tcs :: ClsInst -> [Maybe Name]
is_tcs = [Maybe Name]
rough_tcs1 })
| [FunDep TyVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FunDep TyVar]
fds
= []
| Bool
otherwise
= (ClsInst -> ClsInst -> Bool) -> [ClsInst] -> [ClsInst]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy ClsInst -> ClsInst -> Bool
eq_inst ([ClsInst] -> [ClsInst]) -> [ClsInst] -> [ClsInst]
forall a b. (a -> b) -> a -> b
$
[ ClsInst
ispec | ClsInst
ispec <- [ClsInst]
cls_insts
, FunDep TyVar
fd <- [FunDep TyVar]
fds
, FunDep TyVar -> ClsInst -> Bool
is_inconsistent FunDep TyVar
fd ClsInst
ispec ]
where
cls_insts :: [ClsInst]
cls_insts = InstEnvs -> Class -> [ClsInst]
classInstances InstEnvs
inst_envs Class
cls
([TyVar]
cls_tvs, [FunDep TyVar]
fds) = Class -> ([TyVar], [FunDep TyVar])
classTvsFds Class
cls
qtv_set1 :: VarSet
qtv_set1 = [TyVar] -> VarSet
mkVarSet [TyVar]
qtvs1
is_inconsistent :: FunDep TyVar -> ClsInst -> Bool
is_inconsistent FunDep TyVar
fd (ClsInst { is_tvs :: ClsInst -> [TyVar]
is_tvs = [TyVar]
qtvs2, is_tys :: ClsInst -> [PredType]
is_tys = [PredType]
tys2, is_tcs :: ClsInst -> [Maybe Name]
is_tcs = [Maybe Name]
rough_tcs2 })
| [Maybe Name] -> [Maybe Name] -> Bool
instanceCantMatch [Maybe Name]
trimmed_tcs [Maybe Name]
rough_tcs2
= Bool
False
| Bool
otherwise
= case (TyVar -> BindFlag) -> [PredType] -> [PredType] -> Maybe TCvSubst
tcUnifyTyKis TyVar -> BindFlag
bind_fn [PredType]
ltys1 [PredType]
ltys2 of
Maybe TCvSubst
Nothing -> Bool
False
Just TCvSubst
subst
-> Maybe TCvSubst -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe TCvSubst -> Bool) -> Maybe TCvSubst -> Bool
forall a b. (a -> b) -> a -> b
$
(TyVar -> BindFlag) -> [PredType] -> [PredType] -> Maybe TCvSubst
tcUnifyTyKis TyVar -> BindFlag
bind_fn (TCvSubst -> [PredType] -> [PredType]
substTysUnchecked TCvSubst
subst [PredType]
rtys1) (TCvSubst -> [PredType] -> [PredType]
substTysUnchecked TCvSubst
subst [PredType]
rtys2)
where
trimmed_tcs :: [Maybe Name]
trimmed_tcs = [TyVar] -> FunDep TyVar -> [Maybe Name] -> [Maybe Name]
trimRoughMatchTcs [TyVar]
cls_tvs FunDep TyVar
fd [Maybe Name]
rough_tcs1
([PredType]
ltys1, [PredType]
rtys1) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
cls_tvs [PredType]
tys1
([PredType]
ltys2, [PredType]
rtys2) = FunDep TyVar -> [TyVar] -> [PredType] -> FunDep PredType
instFD FunDep TyVar
fd [TyVar]
cls_tvs [PredType]
tys2
qtv_set2 :: VarSet
qtv_set2 = [TyVar] -> VarSet
mkVarSet [TyVar]
qtvs2
bind_fn :: TyVar -> BindFlag
bind_fn TyVar
tv | TyVar
tv TyVar -> VarSet -> Bool
`elemVarSet` VarSet
qtv_set1 = BindFlag
BindMe
| TyVar
tv TyVar -> VarSet -> Bool
`elemVarSet` VarSet
qtv_set2 = BindFlag
BindMe
| Bool
otherwise = BindFlag
Skolem
eq_inst :: ClsInst -> ClsInst -> Bool
eq_inst ClsInst
i1 ClsInst
i2 = ClsInst -> TyVar
instanceDFunId ClsInst
i1 TyVar -> TyVar -> Bool
forall a. Eq a => a -> a -> Bool
== ClsInst -> TyVar
instanceDFunId ClsInst
i2
trimRoughMatchTcs :: [TyVar] -> FunDep TyVar -> [Maybe Name] -> [Maybe Name]
trimRoughMatchTcs :: [TyVar] -> FunDep TyVar -> [Maybe Name] -> [Maybe Name]
trimRoughMatchTcs [TyVar]
clas_tvs ([TyVar]
ltvs, [TyVar]
_) [Maybe Name]
mb_tcs
= (TyVar -> Maybe Name -> Maybe Name)
-> [TyVar] -> [Maybe Name] -> [Maybe Name]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith TyVar -> Maybe Name -> Maybe Name
forall a. TyVar -> Maybe a -> Maybe a
select [TyVar]
clas_tvs [Maybe Name]
mb_tcs
where
select :: TyVar -> Maybe a -> Maybe a
select TyVar
clas_tv Maybe a
mb_tc | TyVar
clas_tv TyVar -> [TyVar] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [TyVar]
ltvs = Maybe a
mb_tc
| Bool
otherwise = Maybe a
forall a. Maybe a
Nothing