{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module GHC.Tc.Instance.Class (
matchGlobalInst,
ClsInstResult(..),
InstanceWhat(..), safeOverlap, instanceReturnsDictCon,
AssocInstInfo(..), isNotAssociated
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Tc.Utils.Env
import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.TcType
import GHC.Tc.Utils.Instantiate( tcInstType )
import GHC.Tc.Instance.Typeable
import GHC.Tc.Utils.TcMType
import GHC.Tc.Types.Evidence
import GHC.Core.Predicate
import GHC.Rename.Env( addUsedGRE )
import GHC.Types.Name.Reader( lookupGRE_FieldLabel )
import GHC.Core.InstEnv
import GHC.Tc.Utils.Instantiate( instDFunType )
import GHC.Tc.Instance.Family( tcGetFamInstEnvs, tcInstNewTyCon_maybe, tcLookupDataFamInst )
import GHC.Builtin.Types
import GHC.Builtin.Types.Prim( eqPrimTyCon, eqReprPrimTyCon )
import GHC.Builtin.Names
import GHC.Types.Id
import GHC.Core.Type
import GHC.Core.Make ( mkStringExprFS, mkNaturalExpr )
import GHC.Types.Name ( Name, pprDefinedAt )
import GHC.Types.Var.Env ( VarEnv )
import GHC.Core.DataCon
import GHC.Core.TyCon
import GHC.Core.Class
import GHC.Driver.Session
import GHC.Utils.Outputable
import GHC.Utils.Misc( splitAtList, fstOf3 )
import Data.Maybe
data AssocInstInfo
= NotAssociated
| InClsInst { AssocInstInfo -> Class
ai_class :: Class
, AssocInstInfo -> [DFunId]
ai_tyvars :: [TyVar]
, AssocInstInfo -> VarEnv Type
ai_inst_env :: VarEnv Type
}
isNotAssociated :: AssocInstInfo -> Bool
isNotAssociated :: AssocInstInfo -> Bool
isNotAssociated (NotAssociated {}) = Bool
True
isNotAssociated (InClsInst {}) = Bool
False
type SafeOverlapping = Bool
data ClsInstResult
= NoInstance
| OneInst { ClsInstResult -> [Type]
cir_new_theta :: [TcPredType]
, ClsInstResult -> [EvExpr] -> EvTerm
cir_mk_ev :: [EvExpr] -> EvTerm
, ClsInstResult -> InstanceWhat
cir_what :: InstanceWhat }
| NotSure
data InstanceWhat
= BuiltinInstance
| BuiltinEqInstance
| LocalInstance
| TopLevInstance { InstanceWhat -> DFunId
iw_dfun_id :: DFunId
, InstanceWhat -> Bool
iw_safe_over :: SafeOverlapping }
instance Outputable ClsInstResult where
ppr :: ClsInstResult -> SDoc
ppr ClsInstResult
NoInstance = String -> SDoc
text String
"NoInstance"
ppr ClsInstResult
NotSure = String -> SDoc
text String
"NotSure"
ppr (OneInst { cir_new_theta :: ClsInstResult -> [Type]
cir_new_theta = [Type]
ev
, cir_what :: ClsInstResult -> InstanceWhat
cir_what = InstanceWhat
what })
= String -> SDoc
text String
"OneInst" SDoc -> SDoc -> SDoc
<+> [SDoc] -> SDoc
vcat [[Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
ev, InstanceWhat -> SDoc
forall a. Outputable a => a -> SDoc
ppr InstanceWhat
what]
instance Outputable InstanceWhat where
ppr :: InstanceWhat -> SDoc
ppr InstanceWhat
BuiltinInstance = String -> SDoc
text String
"a built-in instance"
ppr InstanceWhat
BuiltinEqInstance = String -> SDoc
text String
"a built-in equality instance"
ppr InstanceWhat
LocalInstance = String -> SDoc
text String
"a locally-quantified instance"
ppr (TopLevInstance { iw_dfun_id :: InstanceWhat -> DFunId
iw_dfun_id = DFunId
dfun })
= SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text String
"instance" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
pprSigmaType (DFunId -> Type
idType DFunId
dfun))
Int
2 (String -> SDoc
text String
"--" SDoc -> SDoc -> SDoc
<+> Name -> SDoc
pprDefinedAt (DFunId -> Name
idName DFunId
dfun))
safeOverlap :: InstanceWhat -> Bool
safeOverlap :: InstanceWhat -> Bool
safeOverlap (TopLevInstance { iw_safe_over :: InstanceWhat -> Bool
iw_safe_over = Bool
so }) = Bool
so
safeOverlap InstanceWhat
_ = Bool
True
instanceReturnsDictCon :: InstanceWhat -> Bool
instanceReturnsDictCon :: InstanceWhat -> Bool
instanceReturnsDictCon (TopLevInstance {}) = Bool
True
instanceReturnsDictCon InstanceWhat
BuiltinInstance = Bool
True
instanceReturnsDictCon InstanceWhat
BuiltinEqInstance = Bool
False
instanceReturnsDictCon InstanceWhat
LocalInstance = Bool
False
matchGlobalInst :: DynFlags
-> Bool
-> Class -> [Type] -> TcM ClsInstResult
matchGlobalInst :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchGlobalInst DynFlags
dflags Bool
short_cut Class
clas [Type]
tys
| Name
cls_name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
knownNatClassName
= DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchKnownNat DynFlags
dflags Bool
short_cut Class
clas [Type]
tys
| Name
cls_name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
knownSymbolClassName
= DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchKnownSymbol DynFlags
dflags Bool
short_cut Class
clas [Type]
tys
| Class -> Bool
isCTupleClass Class
clas = Class -> [Type] -> TcM ClsInstResult
matchCTuple Class
clas [Type]
tys
| Name
cls_name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
typeableClassName = Class -> [Type] -> TcM ClsInstResult
matchTypeable Class
clas [Type]
tys
| Class
clas Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
heqTyConKey = [Type] -> TcM ClsInstResult
matchHeteroEquality [Type]
tys
| Class
clas Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqTyConKey = [Type] -> TcM ClsInstResult
matchHomoEquality [Type]
tys
| Class
clas Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
coercibleTyConKey = [Type] -> TcM ClsInstResult
matchCoercible [Type]
tys
| Name
cls_name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
hasFieldClassName = DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchHasField DynFlags
dflags Bool
short_cut Class
clas [Type]
tys
| Bool
otherwise = DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv DynFlags
dflags Bool
short_cut Class
clas [Type]
tys
where
cls_name :: Name
cls_name = Class -> Name
className Class
clas
matchInstEnv :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv DynFlags
dflags Bool
short_cut_solver Class
clas [Type]
tys
= do { InstEnvs
instEnvs <- TcM InstEnvs
tcGetInstEnvs
; let safeOverlapCheck :: Bool
safeOverlapCheck = DynFlags -> SafeHaskellMode
safeHaskell DynFlags
dflags SafeHaskellMode -> [SafeHaskellMode] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [SafeHaskellMode
Sf_Safe, SafeHaskellMode
Sf_Trustworthy]
([InstMatch]
matches, [ClsInst]
unify, [InstMatch]
unsafeOverlaps) = Bool
-> InstEnvs
-> Class
-> [Type]
-> ([InstMatch], [ClsInst], [InstMatch])
lookupInstEnv Bool
True InstEnvs
instEnvs Class
clas [Type]
tys
safeHaskFail :: Bool
safeHaskFail = Bool
safeOverlapCheck Bool -> Bool -> Bool
&& Bool -> Bool
not ([InstMatch] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InstMatch]
unsafeOverlaps)
; String -> SDoc -> TcRn ()
traceTc String
"matchInstEnv" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text String
"goal:" SDoc -> SDoc -> SDoc
<+> Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
clas SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys
, String -> SDoc
text String
"matches:" SDoc -> SDoc -> SDoc
<+> [InstMatch] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [InstMatch]
matches
, String -> SDoc
text String
"unify:" SDoc -> SDoc -> SDoc
<+> [ClsInst] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ClsInst]
unify ]
; case ([InstMatch]
matches, [ClsInst]
unify, Bool
safeHaskFail) of
([], [], Bool
_)
-> do { String -> SDoc -> TcRn ()
traceTc String
"matchClass not matching" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred)
; ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NoInstance }
([(ClsInst
ispec, [DFunInstType]
inst_tys)], [], Bool
False)
| Bool
short_cut_solver
, ClsInst -> Bool
isOverlappable ClsInst
ispec
-> do { String -> SDoc -> TcRn ()
traceTc String
"matchClass: ignoring overlappable" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred)
; ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NotSure }
| Bool
otherwise
-> do { let dfun_id :: DFunId
dfun_id = ClsInst -> DFunId
instanceDFunId ClsInst
ispec
; String -> SDoc -> TcRn ()
traceTc String
"matchClass success" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [String -> SDoc
text String
"dict" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred,
String -> SDoc
text String
"witness" SDoc -> SDoc -> SDoc
<+> DFunId -> SDoc
forall a. Outputable a => a -> SDoc
ppr DFunId
dfun_id
SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DFunId -> Type
idType DFunId
dfun_id) ]
; Bool -> DFunId -> [DFunInstType] -> TcM ClsInstResult
match_one ([InstMatch] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InstMatch]
unsafeOverlaps) DFunId
dfun_id [DFunInstType]
inst_tys }
([InstMatch], [ClsInst], Bool)
_ -> do { String -> SDoc -> TcRn ()
traceTc String
"matchClass multiple matches, deferring choice" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [String -> SDoc
text String
"dict" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred,
String -> SDoc
text String
"matches" SDoc -> SDoc -> SDoc
<+> [InstMatch] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [InstMatch]
matches]
; ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NotSure } }
where
pred :: Type
pred = Class -> [Type] -> Type
mkClassPred Class
clas [Type]
tys
match_one :: SafeOverlapping -> DFunId -> [DFunInstType] -> TcM ClsInstResult
match_one :: Bool -> DFunId -> [DFunInstType] -> TcM ClsInstResult
match_one Bool
so DFunId
dfun_id [DFunInstType]
mb_inst_tys
= do { String -> SDoc -> TcRn ()
traceTc String
"match_one" (DFunId -> SDoc
forall a. Outputable a => a -> SDoc
ppr DFunId
dfun_id SDoc -> SDoc -> SDoc
$$ [DFunInstType] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [DFunInstType]
mb_inst_tys)
; ([Type]
tys, [Type]
theta) <- DFunId -> [DFunInstType] -> TcM ([Type], [Type])
instDFunType DFunId
dfun_id [DFunInstType]
mb_inst_tys
; String -> SDoc -> TcRn ()
traceTc String
"match_one 2" (DFunId -> SDoc
forall a. Outputable a => a -> SDoc
ppr DFunId
dfun_id SDoc -> SDoc -> SDoc
$$ [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys SDoc -> SDoc -> SDoc
$$ [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
theta)
; ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ClsInstResult -> TcM ClsInstResult)
-> ClsInstResult -> TcM ClsInstResult
forall a b. (a -> b) -> a -> b
$ OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [Type]
theta
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = DFunId -> [Type] -> [EvExpr] -> EvTerm
evDFunApp DFunId
dfun_id [Type]
tys
, cir_what :: InstanceWhat
cir_what = TopLevInstance :: DFunId -> Bool -> InstanceWhat
TopLevInstance { iw_dfun_id :: DFunId
iw_dfun_id = DFunId
dfun_id
, iw_safe_over :: Bool
iw_safe_over = Bool
so } } }
matchCTuple :: Class -> [Type] -> TcM ClsInstResult
matchCTuple :: Class -> [Type] -> TcM ClsInstResult
matchCTuple Class
clas [Type]
tys
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [Type]
tys
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = [EvExpr] -> EvTerm
tuple_ev
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance })
where
data_con :: DataCon
data_con = TyCon -> DataCon
tyConSingleDataCon (Class -> TyCon
classTyCon Class
clas)
tuple_ev :: [EvExpr] -> EvTerm
tuple_ev = DFunId -> [Type] -> [EvExpr] -> EvTerm
evDFunApp (DataCon -> DFunId
dataConWrapId DataCon
data_con) [Type]
tys
matchKnownNat :: DynFlags
-> Bool
-> Class -> [Type] -> TcM ClsInstResult
matchKnownNat :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchKnownNat DynFlags
_ Bool
_ Class
clas [Type
ty]
| Just Integer
n <- Type -> Maybe Integer
isNumLitTy Type
ty = Class -> Type -> EvExpr -> TcM ClsInstResult
makeLitDict Class
clas Type
ty (Integer -> EvExpr
mkNaturalExpr Integer
n)
matchKnownNat DynFlags
df Bool
sc Class
clas [Type]
tys = DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv DynFlags
df Bool
sc Class
clas [Type]
tys
matchKnownSymbol :: DynFlags
-> Bool
-> Class -> [Type] -> TcM ClsInstResult
matchKnownSymbol :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchKnownSymbol DynFlags
_ Bool
_ Class
clas [Type
ty]
| Just FastString
s <- Type -> Maybe FastString
isStrLitTy Type
ty = do
EvExpr
et <- FastString -> IOEnv (Env TcGblEnv TcLclEnv) EvExpr
forall (m :: * -> *). MonadThings m => FastString -> m EvExpr
mkStringExprFS FastString
s
Class -> Type -> EvExpr -> TcM ClsInstResult
makeLitDict Class
clas Type
ty EvExpr
et
matchKnownSymbol DynFlags
df Bool
sc Class
clas [Type]
tys = DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv DynFlags
df Bool
sc Class
clas [Type]
tys
makeLitDict :: Class -> Type -> EvExpr -> TcM ClsInstResult
makeLitDict :: Class -> Type -> EvExpr -> TcM ClsInstResult
makeLitDict Class
clas Type
ty EvExpr
et
| Just (Type
_, TcCoercion
co_dict) <- TyCon -> [Type] -> Maybe (Type, TcCoercion)
tcInstNewTyCon_maybe (Class -> TyCon
classTyCon Class
clas) [Type
ty]
, [ DFunId
meth ] <- Class -> [DFunId]
classMethods Class
clas
, Just TyCon
tcRep <- Type -> Maybe TyCon
tyConAppTyCon_maybe (DFunId -> Type
classMethodTy DFunId
meth)
, Just (Type
_, TcCoercion
co_rep) <- TyCon -> [Type] -> Maybe (Type, TcCoercion)
tcInstNewTyCon_maybe TyCon
tcRep [Type
ty]
, let ev_tm :: EvTerm
ev_tm = EvExpr -> TcCoercion -> EvTerm
mkEvCast EvExpr
et (TcCoercion -> TcCoercion
mkTcSymCo (TcCoercion -> TcCoercion -> TcCoercion
mkTcTransCo TcCoercion
co_dict TcCoercion
co_rep))
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ClsInstResult -> TcM ClsInstResult)
-> ClsInstResult -> TcM ClsInstResult
forall a b. (a -> b) -> a -> b
$ OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = []
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = \[EvExpr]
_ -> EvTerm
ev_tm
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance }
| Bool
otherwise
= String -> SDoc -> TcM ClsInstResult
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"makeLitDict" (SDoc -> TcM ClsInstResult) -> SDoc -> TcM ClsInstResult
forall a b. (a -> b) -> a -> b
$
String -> SDoc
text String
"Unexpected evidence for" SDoc -> SDoc -> SDoc
<+> Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Class -> Name
className Class
clas)
SDoc -> SDoc -> SDoc
$$ [SDoc] -> SDoc
vcat ((DFunId -> SDoc) -> [DFunId] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Type -> SDoc) -> (DFunId -> Type) -> DFunId -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DFunId -> Type
idType) (Class -> [DFunId]
classMethods Class
clas))
matchTypeable :: Class -> [Type] -> TcM ClsInstResult
matchTypeable :: Class -> [Type] -> TcM ClsInstResult
matchTypeable Class
clas [Type
k,Type
t]
| Type -> Bool
isForAllTy Type
k = ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NoInstance
| Maybe (Type, Type) -> Bool
forall a. Maybe a -> Bool
isJust (Type -> Maybe (Type, Type)
tcSplitPredFunTy_maybe Type
t) = ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NoInstance
| Type
k Type -> Type -> Bool
`eqType` Type
typeNatKind = Name -> Type -> TcM ClsInstResult
doTyLit Name
knownNatClassName Type
t
| Type
k Type -> Type -> Bool
`eqType` Type
typeSymbolKind = Name -> Type -> TcM ClsInstResult
doTyLit Name
knownSymbolClassName Type
t
| Type -> Bool
tcIsConstraintKind Type
t = Class -> Type -> TyCon -> [Type] -> TcM ClsInstResult
doTyConApp Class
clas Type
t TyCon
constraintKindTyCon []
| Just (Type
mult,Type
arg,Type
ret) <- Type -> Maybe (Type, Type, Type)
splitFunTy_maybe Type
t = Class -> Type -> Type -> Type -> Type -> TcM ClsInstResult
doFunTy Class
clas Type
t Type
mult Type
arg Type
ret
| Just (TyCon
tc, [Type]
ks) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
t
, TyCon -> [Type] -> Bool
onlyNamedBndrsApplied TyCon
tc [Type]
ks = Class -> Type -> TyCon -> [Type] -> TcM ClsInstResult
doTyConApp Class
clas Type
t TyCon
tc [Type]
ks
| Just (Type
f,Type
kt) <- Type -> Maybe (Type, Type)
splitAppTy_maybe Type
t = Class -> Type -> Type -> Type -> TcM ClsInstResult
doTyApp Class
clas Type
t Type
f Type
kt
matchTypeable Class
_ [Type]
_ = ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NoInstance
doFunTy :: Class -> Type -> Mult -> Type -> Type -> TcM ClsInstResult
doFunTy :: Class -> Type -> Type -> Type -> Type -> TcM ClsInstResult
doFunTy Class
clas Type
ty Type
mult Type
arg_ty Type
ret_ty
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ClsInstResult -> TcM ClsInstResult)
-> ClsInstResult -> TcM ClsInstResult
forall a b. (a -> b) -> a -> b
$ OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [Type]
preds
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = [EvExpr] -> EvTerm
mk_ev
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance }
where
preds :: [Type]
preds = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Class -> Type -> Type
mk_typeable_pred Class
clas) [Type
mult, Type
arg_ty, Type
ret_ty]
mk_ev :: [EvExpr] -> EvTerm
mk_ev [EvExpr
mult_ev, EvExpr
arg_ev, EvExpr
ret_ev] = Type -> EvTypeable -> EvTerm
evTypeable Type
ty (EvTypeable -> EvTerm) -> EvTypeable -> EvTerm
forall a b. (a -> b) -> a -> b
$
EvTerm -> EvTerm -> EvTerm -> EvTypeable
EvTypeableTrFun (EvExpr -> EvTerm
EvExpr EvExpr
mult_ev) (EvExpr -> EvTerm
EvExpr EvExpr
arg_ev) (EvExpr -> EvTerm
EvExpr EvExpr
ret_ev)
mk_ev [EvExpr]
_ = String -> EvTerm
forall a. String -> a
panic String
"GHC.Tc.Solver.Interact.doFunTy"
doTyConApp :: Class -> Type -> TyCon -> [Kind] -> TcM ClsInstResult
doTyConApp :: Class -> Type -> TyCon -> [Type] -> TcM ClsInstResult
doTyConApp Class
clas Type
ty TyCon
tc [Type]
kind_args
| TyCon -> Bool
tyConIsTypeable TyCon
tc
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ClsInstResult -> TcM ClsInstResult)
-> ClsInstResult -> TcM ClsInstResult
forall a b. (a -> b) -> a -> b
$ OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Class -> Type -> Type
mk_typeable_pred Class
clas) [Type]
kind_args)
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = [EvExpr] -> EvTerm
mk_ev
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance }
| Bool
otherwise
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NoInstance
where
mk_ev :: [EvExpr] -> EvTerm
mk_ev [EvExpr]
kinds = Type -> EvTypeable -> EvTerm
evTypeable Type
ty (EvTypeable -> EvTerm) -> EvTypeable -> EvTerm
forall a b. (a -> b) -> a -> b
$ TyCon -> [EvTerm] -> EvTypeable
EvTypeableTyCon TyCon
tc ((EvExpr -> EvTerm) -> [EvExpr] -> [EvTerm]
forall a b. (a -> b) -> [a] -> [b]
map EvExpr -> EvTerm
EvExpr [EvExpr]
kinds)
onlyNamedBndrsApplied :: TyCon -> [KindOrType] -> Bool
onlyNamedBndrsApplied :: TyCon -> [Type] -> Bool
onlyNamedBndrsApplied TyCon
tc [Type]
ks
= (TyConBinder -> Bool) -> [TyConBinder] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all TyConBinder -> Bool
isNamedTyConBinder [TyConBinder]
used_bndrs Bool -> Bool -> Bool
&&
Bool -> Bool
not ((TyConBinder -> Bool) -> [TyConBinder] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TyConBinder -> Bool
isNamedTyConBinder [TyConBinder]
leftover_bndrs)
where
bndrs :: [TyConBinder]
bndrs = TyCon -> [TyConBinder]
tyConBinders TyCon
tc
([TyConBinder]
used_bndrs, [TyConBinder]
leftover_bndrs) = [Type] -> [TyConBinder] -> ([TyConBinder], [TyConBinder])
forall b a. [b] -> [a] -> ([a], [a])
splitAtList [Type]
ks [TyConBinder]
bndrs
doTyApp :: Class -> Type -> Type -> KindOrType -> TcM ClsInstResult
doTyApp :: Class -> Type -> Type -> Type -> TcM ClsInstResult
doTyApp Class
clas Type
ty Type
f Type
tk
| Type -> Bool
isForAllTy (HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
f)
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return ClsInstResult
NoInstance
| Bool
otherwise
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (ClsInstResult -> TcM ClsInstResult)
-> ClsInstResult -> TcM ClsInstResult
forall a b. (a -> b) -> a -> b
$ OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Class -> Type -> Type
mk_typeable_pred Class
clas) [Type
f, Type
tk]
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = [EvExpr] -> EvTerm
mk_ev
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance }
where
mk_ev :: [EvExpr] -> EvTerm
mk_ev [EvExpr
t1,EvExpr
t2] = Type -> EvTypeable -> EvTerm
evTypeable Type
ty (EvTypeable -> EvTerm) -> EvTypeable -> EvTerm
forall a b. (a -> b) -> a -> b
$ EvTerm -> EvTerm -> EvTypeable
EvTypeableTyApp (EvExpr -> EvTerm
EvExpr EvExpr
t1) (EvExpr -> EvTerm
EvExpr EvExpr
t2)
mk_ev [EvExpr]
_ = String -> EvTerm
forall a. String -> a
panic String
"doTyApp"
mk_typeable_pred :: Class -> Type -> PredType
mk_typeable_pred :: Class -> Type -> Type
mk_typeable_pred Class
clas Type
ty = Class -> [Type] -> Type
mkClassPred Class
clas [ HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
ty, Type
ty ]
doTyLit :: Name -> Type -> TcM ClsInstResult
doTyLit :: Name -> Type -> TcM ClsInstResult
doTyLit Name
kc Type
t = do { Class
kc_clas <- Name -> TcM Class
tcLookupClass Name
kc
; let kc_pred :: Type
kc_pred = Class -> [Type] -> Type
mkClassPred Class
kc_clas [ Type
t ]
mk_ev :: [EvExpr] -> EvTerm
mk_ev [EvExpr
ev] = Type -> EvTypeable -> EvTerm
evTypeable Type
t (EvTypeable -> EvTerm) -> EvTypeable -> EvTerm
forall a b. (a -> b) -> a -> b
$ EvTerm -> EvTypeable
EvTypeableTyLit (EvExpr -> EvTerm
EvExpr EvExpr
ev)
mk_ev [EvExpr]
_ = String -> EvTerm
forall a. String -> a
panic String
"doTyLit"
; ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [Type
kc_pred]
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = [EvExpr] -> EvTerm
mk_ev
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance }) }
matchHeteroEquality :: [Type] -> TcM ClsInstResult
matchHeteroEquality :: [Type] -> TcM ClsInstResult
matchHeteroEquality [Type]
args
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [ TyCon -> [Type] -> Type
mkTyConApp TyCon
eqPrimTyCon [Type]
args ]
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = DataCon -> [Type] -> [EvExpr] -> EvTerm
evDataConApp DataCon
heqDataCon [Type]
args
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinEqInstance })
matchHomoEquality :: [Type] -> TcM ClsInstResult
matchHomoEquality :: [Type] -> TcM ClsInstResult
matchHomoEquality args :: [Type]
args@[Type
k,Type
t1,Type
t2]
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [ TyCon -> [Type] -> Type
mkTyConApp TyCon
eqPrimTyCon [Type
k,Type
k,Type
t1,Type
t2] ]
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = DataCon -> [Type] -> [EvExpr] -> EvTerm
evDataConApp DataCon
eqDataCon [Type]
args
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinEqInstance })
matchHomoEquality [Type]
args = String -> SDoc -> TcM ClsInstResult
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"matchHomoEquality" ([Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
args)
matchCoercible :: [Type] -> TcM ClsInstResult
matchCoercible :: [Type] -> TcM ClsInstResult
matchCoercible args :: [Type]
args@[Type
k, Type
t1, Type
t2]
= ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return (OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [ TyCon -> [Type] -> Type
mkTyConApp TyCon
eqReprPrimTyCon [Type]
args' ]
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = DataCon -> [Type] -> [EvExpr] -> EvTerm
evDataConApp DataCon
coercibleDataCon [Type]
args
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinEqInstance })
where
args' :: [Type]
args' = [Type
k, Type
k, Type
t1, Type
t2]
matchCoercible [Type]
args = String -> SDoc -> TcM ClsInstResult
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"matchLiftedCoercible" ([Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
args)
matchHasField :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchHasField :: DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchHasField DynFlags
dflags Bool
short_cut Class
clas [Type]
tys
= do { FamInstEnvs
fam_inst_envs <- TcM FamInstEnvs
tcGetFamInstEnvs
; GlobalRdrEnv
rdr_env <- TcRn GlobalRdrEnv
getGlobalRdrEnv
; case [Type]
tys of
[Type
_k_ty, Type
x_ty, Type
r_ty, Type
a_ty]
| Just FastString
x <- Type -> Maybe FastString
isStrLitTy Type
x_ty
, Just (TyCon
tc, [Type]
args) <- HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe Type
r_ty
, let r_tc :: TyCon
r_tc = (TyCon, [Type], TcCoercion) -> TyCon
forall a b c. (a, b, c) -> a
fstOf3 (FamInstEnvs -> TyCon -> [Type] -> (TyCon, [Type], TcCoercion)
tcLookupDataFamInst FamInstEnvs
fam_inst_envs TyCon
tc [Type]
args)
, Just FieldLabel
fl <- FastString -> TyCon -> Maybe FieldLabel
lookupTyConFieldLabel FastString
x TyCon
r_tc
, Just GlobalRdrElt
gre <- GlobalRdrEnv -> FieldLabel -> Maybe GlobalRdrElt
lookupGRE_FieldLabel GlobalRdrEnv
rdr_env FieldLabel
fl
-> do { DFunId
sel_id <- Name -> TcM DFunId
tcLookupId (FieldLabel -> Name
forall a. FieldLbl a -> a
flSelector FieldLabel
fl)
; ([(Name, DFunId)]
tv_prs, [Type]
preds, Type
sel_ty) <- ([DFunId] -> TcM (TCvSubst, [DFunId]))
-> DFunId -> TcM ([(Name, DFunId)], [Type], Type)
tcInstType [DFunId] -> TcM (TCvSubst, [DFunId])
newMetaTyVars DFunId
sel_id
; let theta :: [Type]
theta = Type -> Type -> Type
mkPrimEqPred Type
sel_ty (Type -> Type -> Type
mkVisFunTyMany Type
r_ty Type
a_ty) Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
preds
mk_ev :: [EvExpr] -> EvTerm
mk_ev (EvExpr
ev1:[EvExpr]
evs) = DFunId -> [Type] -> [EvExpr] -> EvExpr
evSelector DFunId
sel_id [Type]
tvs [EvExpr]
evs EvExpr -> TcCoercion -> EvTerm
`evCast` TcCoercion
co
where
co :: TcCoercion
co = TcCoercion -> TcCoercion
mkTcSubCo (EvTerm -> TcCoercion
evTermCoercion (EvExpr -> EvTerm
EvExpr EvExpr
ev1))
TcCoercion -> TcCoercion -> TcCoercion
`mkTcTransCo` TcCoercion -> TcCoercion
mkTcSymCo TcCoercion
co2
mk_ev [] = String -> EvTerm
forall a. String -> a
panic String
"matchHasField.mk_ev"
Just (Type
_, TcCoercion
co2) = TyCon -> [Type] -> Maybe (Type, TcCoercion)
tcInstNewTyCon_maybe (Class -> TyCon
classTyCon Class
clas)
[Type]
tys
tvs :: [Type]
tvs = [DFunId] -> [Type]
mkTyVarTys (((Name, DFunId) -> DFunId) -> [(Name, DFunId)] -> [DFunId]
forall a b. (a -> b) -> [a] -> [b]
map (Name, DFunId) -> DFunId
forall a b. (a, b) -> b
snd [(Name, DFunId)]
tv_prs)
; if Bool -> Bool
not (DFunId -> Bool
isNaughtyRecordSelector DFunId
sel_id) Bool -> Bool -> Bool
&& Type -> Bool
isTauTy Type
sel_ty
then do { Bool -> GlobalRdrElt -> TcRn ()
addUsedGRE Bool
True GlobalRdrElt
gre
; ClsInstResult -> TcM ClsInstResult
forall (m :: * -> *) a. Monad m => a -> m a
return OneInst :: [Type] -> ([EvExpr] -> EvTerm) -> InstanceWhat -> ClsInstResult
OneInst { cir_new_theta :: [Type]
cir_new_theta = [Type]
theta
, cir_mk_ev :: [EvExpr] -> EvTerm
cir_mk_ev = [EvExpr] -> EvTerm
mk_ev
, cir_what :: InstanceWhat
cir_what = InstanceWhat
BuiltinInstance } }
else DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv DynFlags
dflags Bool
short_cut Class
clas [Type]
tys }
[Type]
_ -> DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchInstEnv DynFlags
dflags Bool
short_cut Class
clas [Type]
tys }