{-# LANGUAGE CPP, DeriveDataTypeable #-}
module GHC.Core.InstEnv (
DFunId, InstMatch, ClsInstLookupResult,
OverlapFlag(..), OverlapMode(..), setOverlapModeMaybe,
ClsInst(..), DFunInstType, pprInstance, pprInstanceHdr, pprInstances,
instanceHead, instanceSig, mkLocalInstance, mkImportedInstance,
instanceDFunId, updateClsInstDFun, instanceRoughTcs,
fuzzyClsInstCmp, orphNamesOfClsInst,
InstEnvs(..), VisibleOrphanModules, InstEnv,
emptyInstEnv, extendInstEnv,
deleteFromInstEnv, deleteDFunFromInstEnv,
identicalClsInstHead,
extendInstEnvList, lookupUniqueInstEnv, lookupInstEnv, instEnvElts, instEnvClasses,
memberInstEnv,
instIsVisible,
classInstances, instanceBindFun,
instanceCantMatch, roughMatchTcs,
isOverlappable, isOverlapping, isIncoherent
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Tc.Utils.TcType
import GHC.Core ( IsOrphan(..), isOrphan, chooseOrphanAnchor )
import GHC.Unit.Module.Env
import GHC.Unit.Types
import GHC.Core.Class
import GHC.Types.Var
import GHC.Types.Var.Set
import GHC.Types.Name
import GHC.Types.Name.Set
import GHC.Types.Unique (getUnique)
import GHC.Core.Unify
import GHC.Types.Basic
import GHC.Types.Unique.DFM
import GHC.Types.Id
import Data.Data ( Data )
import Data.Maybe ( isJust )
import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Utils.Panic
data ClsInst
= ClsInst {
ClsInst -> Name
is_cls_nm :: Name
, ClsInst -> [RoughMatchTc]
is_tcs :: [RoughMatchTc]
, ClsInst -> Name
is_dfun_name :: Name
, ClsInst -> [DFunId]
is_tvs :: [TyVar]
, ClsInst -> Class
is_cls :: Class
, ClsInst -> [Type]
is_tys :: [Type]
, ClsInst -> DFunId
is_dfun :: DFunId
, ClsInst -> OverlapFlag
is_flag :: OverlapFlag
, ClsInst -> IsOrphan
is_orphan :: IsOrphan
}
deriving Typeable ClsInst
Typeable ClsInst
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClsInst -> c ClsInst)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClsInst)
-> (ClsInst -> Constr)
-> (ClsInst -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ClsInst))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ClsInst))
-> ((forall b. Data b => b -> b) -> ClsInst -> ClsInst)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r)
-> (forall u. (forall d. Data d => d -> u) -> ClsInst -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> ClsInst -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst)
-> Data ClsInst
ClsInst -> DataType
ClsInst -> Constr
(forall b. Data b => b -> b) -> ClsInst -> ClsInst
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) -> ClsInst -> u
forall u. (forall d. Data d => d -> u) -> ClsInst -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClsInst
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClsInst -> c ClsInst
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ClsInst)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ClsInst)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ClsInst -> m ClsInst
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ClsInst -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ClsInst -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> ClsInst -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ClsInst -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ClsInst -> r
gmapT :: (forall b. Data b => b -> b) -> ClsInst -> ClsInst
$cgmapT :: (forall b. Data b => b -> b) -> ClsInst -> ClsInst
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ClsInst)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c ClsInst)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ClsInst)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ClsInst)
dataTypeOf :: ClsInst -> DataType
$cdataTypeOf :: ClsInst -> DataType
toConstr :: ClsInst -> Constr
$ctoConstr :: ClsInst -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClsInst
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ClsInst
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClsInst -> c ClsInst
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ClsInst -> c ClsInst
Data
fuzzyClsInstCmp :: ClsInst -> ClsInst -> Ordering
fuzzyClsInstCmp :: ClsInst -> ClsInst -> Ordering
fuzzyClsInstCmp ClsInst
x ClsInst
y =
Name -> Name -> Ordering
stableNameCmp (ClsInst -> Name
is_cls_nm ClsInst
x) (ClsInst -> Name
is_cls_nm ClsInst
y) Ordering -> Ordering -> Ordering
forall a. Monoid a => a -> a -> a
`mappend`
[Ordering] -> Ordering
forall a. Monoid a => [a] -> a
mconcat (((RoughMatchTc, RoughMatchTc) -> Ordering)
-> [(RoughMatchTc, RoughMatchTc)] -> [Ordering]
forall a b. (a -> b) -> [a] -> [b]
map (RoughMatchTc, RoughMatchTc) -> Ordering
cmp ([RoughMatchTc] -> [RoughMatchTc] -> [(RoughMatchTc, RoughMatchTc)]
forall a b. [a] -> [b] -> [(a, b)]
zip (ClsInst -> [RoughMatchTc]
is_tcs ClsInst
x) (ClsInst -> [RoughMatchTc]
is_tcs ClsInst
y)))
where
cmp :: (RoughMatchTc, RoughMatchTc) -> Ordering
cmp (RoughMatchTc
OtherTc, RoughMatchTc
OtherTc) = Ordering
EQ
cmp (RoughMatchTc
OtherTc, KnownTc Name
_) = Ordering
LT
cmp (KnownTc Name
_, RoughMatchTc
OtherTc) = Ordering
GT
cmp (KnownTc Name
x, KnownTc Name
y) = Name -> Name -> Ordering
stableNameCmp Name
x Name
y
isOverlappable, isOverlapping, isIncoherent :: ClsInst -> Bool
isOverlappable :: ClsInst -> Bool
isOverlappable ClsInst
i = OverlapMode -> Bool
hasOverlappableFlag (OverlapFlag -> OverlapMode
overlapMode (ClsInst -> OverlapFlag
is_flag ClsInst
i))
isOverlapping :: ClsInst -> Bool
isOverlapping ClsInst
i = OverlapMode -> Bool
hasOverlappingFlag (OverlapFlag -> OverlapMode
overlapMode (ClsInst -> OverlapFlag
is_flag ClsInst
i))
isIncoherent :: ClsInst -> Bool
isIncoherent ClsInst
i = OverlapMode -> Bool
hasIncoherentFlag (OverlapFlag -> OverlapMode
overlapMode (ClsInst -> OverlapFlag
is_flag ClsInst
i))
instanceDFunId :: ClsInst -> DFunId
instanceDFunId :: ClsInst -> DFunId
instanceDFunId = ClsInst -> DFunId
is_dfun
updateClsInstDFun :: (DFunId -> DFunId) -> ClsInst -> ClsInst
updateClsInstDFun :: (DFunId -> DFunId) -> ClsInst -> ClsInst
updateClsInstDFun DFunId -> DFunId
tidy_dfun ClsInst
ispec
= ClsInst
ispec { is_dfun :: DFunId
is_dfun = DFunId -> DFunId
tidy_dfun (ClsInst -> DFunId
is_dfun ClsInst
ispec) }
instanceRoughTcs :: ClsInst -> [RoughMatchTc]
instanceRoughTcs :: ClsInst -> [RoughMatchTc]
instanceRoughTcs = ClsInst -> [RoughMatchTc]
is_tcs
instance NamedThing ClsInst where
getName :: ClsInst -> Name
getName ClsInst
ispec = DFunId -> Name
forall a. NamedThing a => a -> Name
getName (ClsInst -> DFunId
is_dfun ClsInst
ispec)
instance Outputable ClsInst where
ppr :: ClsInst -> SDoc
ppr = ClsInst -> SDoc
pprInstance
pprInstance :: ClsInst -> SDoc
pprInstance :: ClsInst -> SDoc
pprInstance ClsInst
ispec
= SDoc -> Int -> SDoc -> SDoc
hang (ClsInst -> SDoc
pprInstanceHdr ClsInst
ispec)
Int
2 ([SDoc] -> SDoc
vcat [ String -> SDoc
text String
"--" SDoc -> SDoc -> SDoc
<+> Name -> SDoc
pprDefinedAt (ClsInst -> Name
forall a. NamedThing a => a -> Name
getName ClsInst
ispec)
, SDoc -> SDoc
whenPprDebug (DFunId -> SDoc
forall a. Outputable a => a -> SDoc
ppr (ClsInst -> DFunId
is_dfun ClsInst
ispec)) ])
pprInstanceHdr :: ClsInst -> SDoc
pprInstanceHdr :: ClsInst -> SDoc
pprInstanceHdr (ClsInst { is_flag :: ClsInst -> OverlapFlag
is_flag = OverlapFlag
flag, is_dfun :: ClsInst -> DFunId
is_dfun = DFunId
dfun })
= String -> SDoc
text String
"instance" SDoc -> SDoc -> SDoc
<+> OverlapFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr OverlapFlag
flag SDoc -> SDoc -> SDoc
<+> Type -> SDoc
pprSigmaType (DFunId -> Type
idType DFunId
dfun)
pprInstances :: [ClsInst] -> SDoc
pprInstances :: [ClsInst] -> SDoc
pprInstances [ClsInst]
ispecs = [SDoc] -> SDoc
vcat ((ClsInst -> SDoc) -> [ClsInst] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ClsInst -> SDoc
pprInstance [ClsInst]
ispecs)
instanceHead :: ClsInst -> ([TyVar], Class, [Type])
instanceHead :: ClsInst -> ([DFunId], Class, [Type])
instanceHead (ClsInst { is_tvs :: ClsInst -> [DFunId]
is_tvs = [DFunId]
tvs, is_tys :: ClsInst -> [Type]
is_tys = [Type]
tys, is_dfun :: ClsInst -> DFunId
is_dfun = DFunId
dfun })
= ([DFunId]
tvs, Class
cls, [Type]
tys)
where
([DFunId]
_, [Type]
_, Class
cls, [Type]
_) = Type -> ([DFunId], [Type], Class, [Type])
tcSplitDFunTy (DFunId -> Type
idType DFunId
dfun)
orphNamesOfClsInst :: ClsInst -> NameSet
orphNamesOfClsInst :: ClsInst -> NameSet
orphNamesOfClsInst (ClsInst { is_cls_nm :: ClsInst -> Name
is_cls_nm = Name
cls_nm, is_tys :: ClsInst -> [Type]
is_tys = [Type]
tys })
= [Type] -> NameSet
orphNamesOfTypes [Type]
tys NameSet -> NameSet -> NameSet
`unionNameSet` Name -> NameSet
unitNameSet Name
cls_nm
instanceSig :: ClsInst -> ([TyVar], [Type], Class, [Type])
instanceSig :: ClsInst -> ([DFunId], [Type], Class, [Type])
instanceSig ClsInst
ispec = Type -> ([DFunId], [Type], Class, [Type])
tcSplitDFunTy (DFunId -> Type
idType (ClsInst -> DFunId
is_dfun ClsInst
ispec))
mkLocalInstance :: DFunId -> OverlapFlag
-> [TyVar] -> Class -> [Type]
-> ClsInst
mkLocalInstance :: DFunId -> OverlapFlag -> [DFunId] -> Class -> [Type] -> ClsInst
mkLocalInstance DFunId
dfun OverlapFlag
oflag [DFunId]
tvs Class
cls [Type]
tys
= ClsInst { is_flag :: OverlapFlag
is_flag = OverlapFlag
oflag, is_dfun :: DFunId
is_dfun = DFunId
dfun
, is_tvs :: [DFunId]
is_tvs = [DFunId]
tvs
, is_dfun_name :: Name
is_dfun_name = Name
dfun_name
, is_cls :: Class
is_cls = Class
cls, is_cls_nm :: Name
is_cls_nm = Name
cls_name
, is_tys :: [Type]
is_tys = [Type]
tys, is_tcs :: [RoughMatchTc]
is_tcs = [Type] -> [RoughMatchTc]
roughMatchTcs [Type]
tys
, is_orphan :: IsOrphan
is_orphan = IsOrphan
orph
}
where
cls_name :: Name
cls_name = Class -> Name
className Class
cls
dfun_name :: Name
dfun_name = DFunId -> Name
idName DFunId
dfun
this_mod :: Module
this_mod = ASSERT( isExternalName dfun_name ) nameModule dfun_name
is_local :: Name -> Bool
is_local Name
name = Module -> Name -> Bool
nameIsLocalOrFrom Module
this_mod Name
name
([DFunId]
cls_tvs, [FunDep DFunId]
fds) = Class -> ([DFunId], [FunDep DFunId])
classTvsFds Class
cls
arg_names :: [NameSet]
arg_names = [(Name -> Bool) -> NameSet -> NameSet
filterNameSet Name -> Bool
is_local (Type -> NameSet
orphNamesOfType Type
ty) | Type
ty <- [Type]
tys]
orph :: IsOrphan
orph | Name -> Bool
is_local Name
cls_name = OccName -> IsOrphan
NotOrphan (Name -> OccName
nameOccName Name
cls_name)
| (IsOrphan -> Bool) -> [IsOrphan] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all IsOrphan -> Bool
notOrphan [IsOrphan]
mb_ns = ASSERT( not (null mb_ns) ) head mb_ns
| Bool
otherwise = IsOrphan
IsOrphan
notOrphan :: IsOrphan -> Bool
notOrphan NotOrphan{} = Bool
True
notOrphan IsOrphan
_ = Bool
False
mb_ns :: [IsOrphan]
mb_ns :: [IsOrphan]
mb_ns | [FunDep DFunId] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FunDep DFunId]
fds = [[NameSet] -> IsOrphan
choose_one [NameSet]
arg_names]
| Bool
otherwise = (FunDep DFunId -> IsOrphan) -> [FunDep DFunId] -> [IsOrphan]
forall a b. (a -> b) -> [a] -> [b]
map FunDep DFunId -> IsOrphan
do_one [FunDep DFunId]
fds
do_one :: FunDep DFunId -> IsOrphan
do_one ([DFunId]
_ltvs, [DFunId]
rtvs) = [NameSet] -> IsOrphan
choose_one [NameSet
ns | (DFunId
tv,NameSet
ns) <- [DFunId]
cls_tvs [DFunId] -> [NameSet] -> [(DFunId, NameSet)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [NameSet]
arg_names
, Bool -> Bool
not (DFunId
tv DFunId -> [DFunId] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [DFunId]
rtvs)]
choose_one :: [NameSet] -> IsOrphan
choose_one [NameSet]
nss = NameSet -> IsOrphan
chooseOrphanAnchor ([NameSet] -> NameSet
unionNameSets [NameSet]
nss)
mkImportedInstance :: Name
-> [RoughMatchTc]
-> Name
-> DFunId
-> OverlapFlag
-> IsOrphan
-> ClsInst
mkImportedInstance :: Name
-> [RoughMatchTc]
-> Name
-> DFunId
-> OverlapFlag
-> IsOrphan
-> ClsInst
mkImportedInstance Name
cls_nm [RoughMatchTc]
mb_tcs Name
dfun_name DFunId
dfun OverlapFlag
oflag IsOrphan
orphan
= ClsInst { is_flag :: OverlapFlag
is_flag = OverlapFlag
oflag, is_dfun :: DFunId
is_dfun = DFunId
dfun
, is_tvs :: [DFunId]
is_tvs = [DFunId]
tvs, is_tys :: [Type]
is_tys = [Type]
tys
, is_dfun_name :: Name
is_dfun_name = Name
dfun_name
, is_cls_nm :: Name
is_cls_nm = Name
cls_nm, is_cls :: Class
is_cls = Class
cls, is_tcs :: [RoughMatchTc]
is_tcs = [RoughMatchTc]
mb_tcs
, is_orphan :: IsOrphan
is_orphan = IsOrphan
orphan }
where
([DFunId]
tvs, [Type]
_, Class
cls, [Type]
tys) = Type -> ([DFunId], [Type], Class, [Type])
tcSplitDFunTy (DFunId -> Type
idType DFunId
dfun)
type InstEnv = UniqDFM Class ClsInstEnv
data InstEnvs = InstEnvs {
InstEnvs -> InstEnv
ie_global :: InstEnv,
InstEnvs -> InstEnv
ie_local :: InstEnv,
InstEnvs -> VisibleOrphanModules
ie_visible :: VisibleOrphanModules
}
type VisibleOrphanModules = ModuleSet
newtype ClsInstEnv
= ClsIE [ClsInst]
instance Outputable ClsInstEnv where
ppr :: ClsInstEnv -> SDoc
ppr (ClsIE [ClsInst]
is) = [ClsInst] -> SDoc
pprInstances [ClsInst]
is
emptyInstEnv :: InstEnv
emptyInstEnv :: InstEnv
emptyInstEnv = InstEnv
forall key elt. UniqDFM key elt
emptyUDFM
instEnvElts :: InstEnv -> [ClsInst]
instEnvElts :: InstEnv -> [ClsInst]
instEnvElts InstEnv
ie = [ClsInst
elt | ClsIE [ClsInst]
elts <- InstEnv -> [ClsInstEnv]
forall key elt. UniqDFM key elt -> [elt]
eltsUDFM InstEnv
ie, ClsInst
elt <- [ClsInst]
elts]
instEnvClasses :: InstEnv -> [Class]
instEnvClasses :: InstEnv -> [Class]
instEnvClasses InstEnv
ie = [ClsInst -> Class
is_cls ClsInst
e | ClsIE (ClsInst
e : [ClsInst]
_) <- InstEnv -> [ClsInstEnv]
forall key elt. UniqDFM key elt -> [elt]
eltsUDFM InstEnv
ie]
instIsVisible :: VisibleOrphanModules -> ClsInst -> Bool
instIsVisible :: VisibleOrphanModules -> ClsInst -> Bool
instIsVisible VisibleOrphanModules
vis_mods ClsInst
ispec
= case Name -> Maybe Module
nameModule_maybe (ClsInst -> Name
is_dfun_name ClsInst
ispec) of
Maybe Module
Nothing -> Bool
True
Just Module
mod | Module -> Bool
isInteractiveModule Module
mod -> Bool
True
| IsOrphan
IsOrphan <- ClsInst -> IsOrphan
is_orphan ClsInst
ispec -> Module
mod Module -> VisibleOrphanModules -> Bool
`elemModuleSet` VisibleOrphanModules
vis_mods
| Bool
otherwise -> Bool
True
classInstances :: InstEnvs -> Class -> [ClsInst]
classInstances :: InstEnvs -> Class -> [ClsInst]
classInstances (InstEnvs { ie_global :: InstEnvs -> InstEnv
ie_global = InstEnv
pkg_ie, ie_local :: InstEnvs -> InstEnv
ie_local = InstEnv
home_ie, ie_visible :: InstEnvs -> VisibleOrphanModules
ie_visible = VisibleOrphanModules
vis_mods }) Class
cls
= InstEnv -> [ClsInst]
get InstEnv
home_ie [ClsInst] -> [ClsInst] -> [ClsInst]
forall a. [a] -> [a] -> [a]
++ InstEnv -> [ClsInst]
get InstEnv
pkg_ie
where
get :: InstEnv -> [ClsInst]
get InstEnv
env = case InstEnv -> Class -> Maybe ClsInstEnv
forall key elt.
Uniquable key =>
UniqDFM key elt -> key -> Maybe elt
lookupUDFM InstEnv
env Class
cls of
Just (ClsIE [ClsInst]
insts) -> (ClsInst -> Bool) -> [ClsInst] -> [ClsInst]
forall a. (a -> Bool) -> [a] -> [a]
filter (VisibleOrphanModules -> ClsInst -> Bool
instIsVisible VisibleOrphanModules
vis_mods) [ClsInst]
insts
Maybe ClsInstEnv
Nothing -> []
memberInstEnv :: InstEnv -> ClsInst -> Bool
memberInstEnv :: InstEnv -> ClsInst -> Bool
memberInstEnv InstEnv
inst_env ins_item :: ClsInst
ins_item@(ClsInst { is_cls_nm :: ClsInst -> Name
is_cls_nm = Name
cls_nm } ) =
Bool -> (ClsInstEnv -> Bool) -> Maybe ClsInstEnv -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (\(ClsIE [ClsInst]
items) -> (ClsInst -> Bool) -> [ClsInst] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (ClsInst -> ClsInst -> Bool
identicalDFunType ClsInst
ins_item) [ClsInst]
items)
(InstEnv -> Unique -> Maybe ClsInstEnv
forall key elt. UniqDFM key elt -> Unique -> Maybe elt
lookupUDFM_Directly InstEnv
inst_env (Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
cls_nm))
where
identicalDFunType :: ClsInst -> ClsInst -> Bool
identicalDFunType ClsInst
cls1 ClsInst
cls2 =
Type -> Type -> Bool
eqType (DFunId -> Type
varType (ClsInst -> DFunId
is_dfun ClsInst
cls1)) (DFunId -> Type
varType (ClsInst -> DFunId
is_dfun ClsInst
cls2))
extendInstEnvList :: InstEnv -> [ClsInst] -> InstEnv
extendInstEnvList :: InstEnv -> [ClsInst] -> InstEnv
extendInstEnvList InstEnv
inst_env [ClsInst]
ispecs = (InstEnv -> ClsInst -> InstEnv) -> InstEnv -> [ClsInst] -> InstEnv
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' InstEnv -> ClsInst -> InstEnv
extendInstEnv InstEnv
inst_env [ClsInst]
ispecs
extendInstEnv :: InstEnv -> ClsInst -> InstEnv
extendInstEnv :: InstEnv -> ClsInst -> InstEnv
extendInstEnv InstEnv
inst_env ins_item :: ClsInst
ins_item@(ClsInst { is_cls_nm :: ClsInst -> Name
is_cls_nm = Name
cls_nm })
= (ClsInstEnv -> ClsInstEnv -> ClsInstEnv)
-> InstEnv -> Unique -> ClsInstEnv -> InstEnv
forall elt key.
(elt -> elt -> elt)
-> UniqDFM key elt -> Unique -> elt -> UniqDFM key elt
addToUDFM_C_Directly ClsInstEnv -> ClsInstEnv -> ClsInstEnv
add InstEnv
inst_env (Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
cls_nm) ([ClsInst] -> ClsInstEnv
ClsIE [ClsInst
ins_item])
where
add :: ClsInstEnv -> ClsInstEnv -> ClsInstEnv
add (ClsIE [ClsInst]
cur_insts) ClsInstEnv
_ = [ClsInst] -> ClsInstEnv
ClsIE (ClsInst
ins_item ClsInst -> [ClsInst] -> [ClsInst]
forall a. a -> [a] -> [a]
: [ClsInst]
cur_insts)
deleteFromInstEnv :: InstEnv -> ClsInst -> InstEnv
deleteFromInstEnv :: InstEnv -> ClsInst -> InstEnv
deleteFromInstEnv InstEnv
inst_env ins_item :: ClsInst
ins_item@(ClsInst { is_cls_nm :: ClsInst -> Name
is_cls_nm = Name
cls_nm })
= (ClsInstEnv -> ClsInstEnv) -> InstEnv -> Unique -> InstEnv
forall elt key.
(elt -> elt) -> UniqDFM key elt -> Unique -> UniqDFM key elt
adjustUDFM_Directly ClsInstEnv -> ClsInstEnv
adjust InstEnv
inst_env (Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
cls_nm)
where
adjust :: ClsInstEnv -> ClsInstEnv
adjust (ClsIE [ClsInst]
items) = [ClsInst] -> ClsInstEnv
ClsIE ((ClsInst -> Bool) -> [ClsInst] -> [ClsInst]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (ClsInst -> ClsInst -> Bool
identicalClsInstHead ClsInst
ins_item) [ClsInst]
items)
deleteDFunFromInstEnv :: InstEnv -> DFunId -> InstEnv
deleteDFunFromInstEnv :: InstEnv -> DFunId -> InstEnv
deleteDFunFromInstEnv InstEnv
inst_env DFunId
dfun
= (ClsInstEnv -> ClsInstEnv) -> InstEnv -> Class -> InstEnv
forall key elt.
Uniquable key =>
(elt -> elt) -> UniqDFM key elt -> key -> UniqDFM key elt
adjustUDFM ClsInstEnv -> ClsInstEnv
adjust InstEnv
inst_env Class
cls
where
([DFunId]
_, [Type]
_, Class
cls, [Type]
_) = Type -> ([DFunId], [Type], Class, [Type])
tcSplitDFunTy (DFunId -> Type
idType DFunId
dfun)
adjust :: ClsInstEnv -> ClsInstEnv
adjust (ClsIE [ClsInst]
items) = [ClsInst] -> ClsInstEnv
ClsIE ((ClsInst -> Bool) -> [ClsInst] -> [ClsInst]
forall a. (a -> Bool) -> [a] -> [a]
filterOut ClsInst -> Bool
same_dfun [ClsInst]
items)
same_dfun :: ClsInst -> Bool
same_dfun (ClsInst { is_dfun :: ClsInst -> DFunId
is_dfun = DFunId
dfun' }) = DFunId
dfun DFunId -> DFunId -> Bool
forall a. Eq a => a -> a -> Bool
== DFunId
dfun'
identicalClsInstHead :: ClsInst -> ClsInst -> Bool
identicalClsInstHead :: ClsInst -> ClsInst -> Bool
identicalClsInstHead (ClsInst { is_cls_nm :: ClsInst -> Name
is_cls_nm = Name
cls_nm1, is_tcs :: ClsInst -> [RoughMatchTc]
is_tcs = [RoughMatchTc]
rough1, is_tys :: ClsInst -> [Type]
is_tys = [Type]
tys1 })
(ClsInst { is_cls_nm :: ClsInst -> Name
is_cls_nm = Name
cls_nm2, is_tcs :: ClsInst -> [RoughMatchTc]
is_tcs = [RoughMatchTc]
rough2, is_tys :: ClsInst -> [Type]
is_tys = [Type]
tys2 })
= Name
cls_nm1 Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
cls_nm2
Bool -> Bool -> Bool
&& Bool -> Bool
not ([RoughMatchTc] -> [RoughMatchTc] -> Bool
instanceCantMatch [RoughMatchTc]
rough1 [RoughMatchTc]
rough2)
Bool -> Bool -> Bool
&& Maybe TCvSubst -> Bool
forall a. Maybe a -> Bool
isJust ([Type] -> [Type] -> Maybe TCvSubst
tcMatchTys [Type]
tys1 [Type]
tys2)
Bool -> Bool -> Bool
&& Maybe TCvSubst -> Bool
forall a. Maybe a -> Bool
isJust ([Type] -> [Type] -> Maybe TCvSubst
tcMatchTys [Type]
tys2 [Type]
tys1)
type DFunInstType = Maybe Type
type InstMatch = (ClsInst, [DFunInstType])
type ClsInstLookupResult
= ( [InstMatch]
, [ClsInst]
, [InstMatch] )
lookupUniqueInstEnv :: InstEnvs
-> Class -> [Type]
-> Either SDoc (ClsInst, [Type])
lookupUniqueInstEnv :: InstEnvs -> Class -> [Type] -> Either SDoc (ClsInst, [Type])
lookupUniqueInstEnv InstEnvs
instEnv Class
cls [Type]
tys
= case Bool -> InstEnvs -> Class -> [Type] -> ClsInstLookupResult
lookupInstEnv Bool
False InstEnvs
instEnv Class
cls [Type]
tys of
([(ClsInst
inst, [DFunInstType]
inst_tys)], [ClsInst]
_, [InstMatch]
_)
| Bool
noFlexiVar -> (ClsInst, [Type]) -> Either SDoc (ClsInst, [Type])
forall a b. b -> Either a b
Right (ClsInst
inst, [Type]
inst_tys')
| Bool
otherwise -> SDoc -> Either SDoc (ClsInst, [Type])
forall a b. a -> Either a b
Left (SDoc -> Either SDoc (ClsInst, [Type]))
-> SDoc -> Either SDoc (ClsInst, [Type])
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text String
"flexible type variable:" SDoc -> SDoc -> SDoc
<+>
(Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Type -> SDoc) -> Type -> SDoc
forall a b. (a -> b) -> a -> b
$ TyCon -> [Type] -> Type
mkTyConApp (Class -> TyCon
classTyCon Class
cls) [Type]
tys)
where
inst_tys' :: [Type]
inst_tys' = [Type
ty | Just Type
ty <- [DFunInstType]
inst_tys]
noFlexiVar :: Bool
noFlexiVar = (DFunInstType -> Bool) -> [DFunInstType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all DFunInstType -> Bool
forall a. Maybe a -> Bool
isJust [DFunInstType]
inst_tys
ClsInstLookupResult
_other -> SDoc -> Either SDoc (ClsInst, [Type])
forall a b. a -> Either a b
Left (SDoc -> Either SDoc (ClsInst, [Type]))
-> SDoc -> Either SDoc (ClsInst, [Type])
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text String
"instance not found" SDoc -> SDoc -> SDoc
<+>
(Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Type -> SDoc) -> Type -> SDoc
forall a b. (a -> b) -> a -> b
$ TyCon -> [Type] -> Type
mkTyConApp (Class -> TyCon
classTyCon Class
cls) [Type]
tys)
lookupInstEnv' :: InstEnv
-> VisibleOrphanModules
-> Class -> [Type]
-> ([InstMatch],
[ClsInst])
lookupInstEnv' :: InstEnv
-> VisibleOrphanModules
-> Class
-> [Type]
-> ([InstMatch], [ClsInst])
lookupInstEnv' InstEnv
ie VisibleOrphanModules
vis_mods Class
cls [Type]
tys
= InstEnv -> ([InstMatch], [ClsInst])
lookup InstEnv
ie
where
rough_tcs :: [RoughMatchTc]
rough_tcs = [Type] -> [RoughMatchTc]
roughMatchTcs [Type]
tys
lookup :: InstEnv -> ([InstMatch], [ClsInst])
lookup InstEnv
env = case InstEnv -> Class -> Maybe ClsInstEnv
forall key elt.
Uniquable key =>
UniqDFM key elt -> key -> Maybe elt
lookupUDFM InstEnv
env Class
cls of
Maybe ClsInstEnv
Nothing -> ([],[])
Just (ClsIE [ClsInst]
insts) -> [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [] [] [ClsInst]
insts
find :: [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms [ClsInst]
us [] = ([InstMatch]
ms, [ClsInst]
us)
find [InstMatch]
ms [ClsInst]
us (item :: ClsInst
item@(ClsInst { is_tcs :: ClsInst -> [RoughMatchTc]
is_tcs = [RoughMatchTc]
mb_tcs, is_tvs :: ClsInst -> [DFunId]
is_tvs = [DFunId]
tpl_tvs
, is_tys :: ClsInst -> [Type]
is_tys = [Type]
tpl_tys }) : [ClsInst]
rest)
| Bool -> Bool
not (VisibleOrphanModules -> ClsInst -> Bool
instIsVisible VisibleOrphanModules
vis_mods ClsInst
item)
= [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms [ClsInst]
us [ClsInst]
rest
| [RoughMatchTc] -> [RoughMatchTc] -> Bool
instanceCantMatch [RoughMatchTc]
rough_tcs [RoughMatchTc]
mb_tcs
= [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms [ClsInst]
us [ClsInst]
rest
| Just TCvSubst
subst <- [Type] -> [Type] -> Maybe TCvSubst
tcMatchTys [Type]
tpl_tys [Type]
tys
= [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find ((ClsInst
item, (DFunId -> DFunInstType) -> [DFunId] -> [DFunInstType]
forall a b. (a -> b) -> [a] -> [b]
map (TCvSubst -> DFunId -> DFunInstType
lookupTyVar TCvSubst
subst) [DFunId]
tpl_tvs) InstMatch -> [InstMatch] -> [InstMatch]
forall a. a -> [a] -> [a]
: [InstMatch]
ms) [ClsInst]
us [ClsInst]
rest
| ClsInst -> Bool
isIncoherent ClsInst
item
= [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms [ClsInst]
us [ClsInst]
rest
| Bool
otherwise
= ASSERT2( tys_tv_set `disjointVarSet` tpl_tv_set,
(ppr cls <+> ppr tys) $$
(ppr tpl_tvs <+> ppr tpl_tys)
)
case BindFun -> [Type] -> [Type] -> UnifyResult
tcUnifyTysFG BindFun
instanceBindFun [Type]
tpl_tys [Type]
tys of
UnifyResult
SurelyApart -> [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms [ClsInst]
us [ClsInst]
rest
MaybeApart MaybeApartReason
MARInfinite TCvSubst
_ -> [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms [ClsInst]
us [ClsInst]
rest
UnifyResult
_ -> [InstMatch] -> [ClsInst] -> [ClsInst] -> ([InstMatch], [ClsInst])
find [InstMatch]
ms (ClsInst
itemClsInst -> [ClsInst] -> [ClsInst]
forall a. a -> [a] -> [a]
:[ClsInst]
us) [ClsInst]
rest
where
tpl_tv_set :: TyCoVarSet
tpl_tv_set = [DFunId] -> TyCoVarSet
mkVarSet [DFunId]
tpl_tvs
tys_tv_set :: TyCoVarSet
tys_tv_set = [Type] -> TyCoVarSet
tyCoVarsOfTypes [Type]
tys
lookupInstEnv :: Bool
-> InstEnvs
-> Class -> [Type]
-> ClsInstLookupResult
lookupInstEnv :: Bool -> InstEnvs -> Class -> [Type] -> ClsInstLookupResult
lookupInstEnv Bool
check_overlap_safe
(InstEnvs { ie_global :: InstEnvs -> InstEnv
ie_global = InstEnv
pkg_ie
, ie_local :: InstEnvs -> InstEnv
ie_local = InstEnv
home_ie
, ie_visible :: InstEnvs -> VisibleOrphanModules
ie_visible = VisibleOrphanModules
vis_mods })
Class
cls
[Type]
tys
=
([InstMatch]
final_matches, [ClsInst]
final_unifs, [InstMatch]
unsafe_overlapped)
where
([InstMatch]
home_matches, [ClsInst]
home_unifs) = InstEnv
-> VisibleOrphanModules
-> Class
-> [Type]
-> ([InstMatch], [ClsInst])
lookupInstEnv' InstEnv
home_ie VisibleOrphanModules
vis_mods Class
cls [Type]
tys
([InstMatch]
pkg_matches, [ClsInst]
pkg_unifs) = InstEnv
-> VisibleOrphanModules
-> Class
-> [Type]
-> ([InstMatch], [ClsInst])
lookupInstEnv' InstEnv
pkg_ie VisibleOrphanModules
vis_mods Class
cls [Type]
tys
all_matches :: [InstMatch]
all_matches = [InstMatch]
home_matches [InstMatch] -> [InstMatch] -> [InstMatch]
forall a. [a] -> [a] -> [a]
++ [InstMatch]
pkg_matches
all_unifs :: [ClsInst]
all_unifs = [ClsInst]
home_unifs [ClsInst] -> [ClsInst] -> [ClsInst]
forall a. [a] -> [a] -> [a]
++ [ClsInst]
pkg_unifs
final_matches :: [InstMatch]
final_matches = (InstMatch -> [InstMatch] -> [InstMatch])
-> [InstMatch] -> [InstMatch] -> [InstMatch]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr InstMatch -> [InstMatch] -> [InstMatch]
insert_overlapping [] [InstMatch]
all_matches
unsafe_overlapped :: [InstMatch]
unsafe_overlapped
= case [InstMatch]
final_matches of
[InstMatch
match] -> InstMatch -> [InstMatch]
check_safe InstMatch
match
[InstMatch]
_ -> []
final_unifs :: [ClsInst]
final_unifs = case [InstMatch]
final_matches of
(InstMatch
m:[InstMatch]
_) | ClsInst -> Bool
isIncoherent (InstMatch -> ClsInst
forall a b. (a, b) -> a
fst InstMatch
m) -> []
[InstMatch]
_ -> [ClsInst]
all_unifs
check_safe :: InstMatch -> [InstMatch]
check_safe (ClsInst
inst,[DFunInstType]
_)
= case Bool
check_overlap_safe Bool -> Bool -> Bool
&& ClsInst -> Bool
unsafeTopInstance ClsInst
inst of
Bool
True -> [InstMatch] -> [InstMatch] -> [InstMatch]
go [] [InstMatch]
all_matches
Bool
False -> []
where
go :: [InstMatch] -> [InstMatch] -> [InstMatch]
go [InstMatch]
bad [] = [InstMatch]
bad
go [InstMatch]
bad (i :: InstMatch
i@(ClsInst
x,[DFunInstType]
_):[InstMatch]
unchecked) =
if ClsInst -> Bool
inSameMod ClsInst
x Bool -> Bool -> Bool
|| ClsInst -> Bool
isOverlappable ClsInst
x
then [InstMatch] -> [InstMatch] -> [InstMatch]
go [InstMatch]
bad [InstMatch]
unchecked
else [InstMatch] -> [InstMatch] -> [InstMatch]
go (InstMatch
iInstMatch -> [InstMatch] -> [InstMatch]
forall a. a -> [a] -> [a]
:[InstMatch]
bad) [InstMatch]
unchecked
inSameMod :: ClsInst -> Bool
inSameMod ClsInst
b =
let na :: Name
na = Name -> Name
forall a. NamedThing a => a -> Name
getName (Name -> Name) -> Name -> Name
forall a b. (a -> b) -> a -> b
$ ClsInst -> Name
forall a. NamedThing a => a -> Name
getName ClsInst
inst
la :: Bool
la = Name -> Bool
isInternalName Name
na
nb :: Name
nb = Name -> Name
forall a. NamedThing a => a -> Name
getName (Name -> Name) -> Name -> Name
forall a b. (a -> b) -> a -> b
$ ClsInst -> Name
forall a. NamedThing a => a -> Name
getName ClsInst
b
lb :: Bool
lb = Name -> Bool
isInternalName Name
nb
in (Bool
la Bool -> Bool -> Bool
&& Bool
lb) Bool -> Bool -> Bool
|| (HasDebugCallStack => Name -> Module
Name -> Module
nameModule Name
na Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
== HasDebugCallStack => Name -> Module
Name -> Module
nameModule Name
nb)
unsafeTopInstance :: ClsInst -> Bool
unsafeTopInstance ClsInst
inst = OverlapFlag -> Bool
isSafeOverlap (ClsInst -> OverlapFlag
is_flag ClsInst
inst) Bool -> Bool -> Bool
&&
(IsOrphan -> Bool
isOrphan (ClsInst -> IsOrphan
is_orphan ClsInst
inst) Bool -> Bool -> Bool
|| Class -> Int
classArity (ClsInst -> Class
is_cls ClsInst
inst) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1)
insert_overlapping :: InstMatch -> [InstMatch] -> [InstMatch]
insert_overlapping :: InstMatch -> [InstMatch] -> [InstMatch]
insert_overlapping InstMatch
new_item [] = [InstMatch
new_item]
insert_overlapping new_item :: InstMatch
new_item@(ClsInst
new_inst,[DFunInstType]
_) (old_item :: InstMatch
old_item@(ClsInst
old_inst,[DFunInstType]
_) : [InstMatch]
old_items)
| Bool
new_beats_old
, Bool -> Bool
not Bool
old_beats_new
, ClsInst
new_inst ClsInst -> ClsInst -> Bool
`can_override` ClsInst
old_inst
= InstMatch -> [InstMatch] -> [InstMatch]
insert_overlapping InstMatch
new_item [InstMatch]
old_items
| Bool
old_beats_new
, Bool -> Bool
not Bool
new_beats_old
, ClsInst
old_inst ClsInst -> ClsInst -> Bool
`can_override` ClsInst
new_inst
= InstMatch
old_item InstMatch -> [InstMatch] -> [InstMatch]
forall a. a -> [a] -> [a]
: [InstMatch]
old_items
| ClsInst -> Bool
isIncoherent ClsInst
old_inst
= InstMatch -> [InstMatch] -> [InstMatch]
insert_overlapping InstMatch
new_item [InstMatch]
old_items
| ClsInst -> Bool
isIncoherent ClsInst
new_inst
= InstMatch
old_item InstMatch -> [InstMatch] -> [InstMatch]
forall a. a -> [a] -> [a]
: [InstMatch]
old_items
| Bool
otherwise
= InstMatch
old_item InstMatch -> [InstMatch] -> [InstMatch]
forall a. a -> [a] -> [a]
: InstMatch -> [InstMatch] -> [InstMatch]
insert_overlapping InstMatch
new_item [InstMatch]
old_items
where
new_beats_old :: Bool
new_beats_old = ClsInst
new_inst ClsInst -> ClsInst -> Bool
`more_specific_than` ClsInst
old_inst
old_beats_new :: Bool
old_beats_new = ClsInst
old_inst ClsInst -> ClsInst -> Bool
`more_specific_than` ClsInst
new_inst
ClsInst
instA more_specific_than :: ClsInst -> ClsInst -> Bool
`more_specific_than` ClsInst
instB
= Maybe TCvSubst -> Bool
forall a. Maybe a -> Bool
isJust ([Type] -> [Type] -> Maybe TCvSubst
tcMatchTys (ClsInst -> [Type]
is_tys ClsInst
instB) (ClsInst -> [Type]
is_tys ClsInst
instA))
ClsInst
instA can_override :: ClsInst -> ClsInst -> Bool
`can_override` ClsInst
instB
= ClsInst -> Bool
isOverlapping ClsInst
instA Bool -> Bool -> Bool
|| ClsInst -> Bool
isOverlappable ClsInst
instB
instanceBindFun :: BindFun
instanceBindFun :: BindFun
instanceBindFun DFunId
tv Type
_rhs_ty | DFunId -> Bool
isOverlappableTyVar DFunId
tv = BindFlag
Apart
| Bool
otherwise = BindFlag
BindMe