{-# LANGUAGE CPP, TupleSections, ViewPatterns #-}
module TcValidity (
Rank, UserTypeCtxt(..), checkValidType, checkValidMonoType,
checkValidTheta,
checkValidInstance, checkValidInstHead, validDerivPred,
checkTySynRhs,
checkValidCoAxiom, checkValidCoAxBranch,
checkValidTyFamEqn, checkConsistentFamInst,
badATErr, arityErr,
checkValidTelescope,
allDistinctTyVars
) where
#include "HsVersions.h"
import GhcPrelude
import Maybes
import TcUnify ( tcSubType_NC )
import TcSimplify ( simplifyAmbiguityCheck )
import ClsInst ( matchGlobalInst, ClsInstResult(..), InstanceWhat(..), AssocInstInfo(..) )
import TyCoRep
import TcType hiding ( sizeType, sizeTypes )
import TysWiredIn ( heqTyConName, eqTyConName, coercibleTyConName )
import PrelNames
import Type
import Unify ( tcMatchTyX_BM, BindFlag(..) )
import Coercion
import CoAxiom
import Class
import TyCon
import IfaceType( pprIfaceType, pprIfaceTypeApp )
import ToIface( toIfaceType, toIfaceTyCon, toIfaceTcArgs )
import HsSyn
import TcRnMonad
import TcEnv ( tcInitTidyEnv, tcInitOpenTidyEnv )
import FunDeps
import FamInstEnv ( isDominatedBy, injectiveBranches,
InjectivityCheckResult(..) )
import FamInst ( makeInjectivityErrors )
import Name
import VarEnv
import VarSet
import Var ( VarBndr(..), mkTyVar )
import Id ( idType, idName )
import FV
import ErrUtils
import DynFlags
import Util
import ListSetOps
import SrcLoc
import Outputable
import Unique ( mkAlphaTyVarUnique )
import Bag ( emptyBag )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad
import Data.Foldable
import Data.List ( (\\), nub )
import qualified Data.List.NonEmpty as NE
checkAmbiguity :: UserTypeCtxt -> Type -> TcM ()
checkAmbiguity :: UserTypeCtxt -> Type -> TcM ()
checkAmbiguity ctxt :: UserTypeCtxt
ctxt ty :: Type
ty
| UserTypeCtxt -> Bool
wantAmbiguityCheck UserTypeCtxt
ctxt
= do { String -> SDoc -> TcM ()
traceTc "Ambiguity check for" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
; Bool
allow_ambiguous <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.AllowAmbiguousTypes
; (_wrap :: HsWrapper
_wrap, wanted :: WantedConstraints
wanted) <- SDoc
-> TcM (HsWrapper, WantedConstraints)
-> TcM (HsWrapper, WantedConstraints)
forall a. SDoc -> TcM a -> TcM a
addErrCtxt (Bool -> SDoc
mk_msg Bool
allow_ambiguous) (TcM (HsWrapper, WantedConstraints)
-> TcM (HsWrapper, WantedConstraints))
-> TcM (HsWrapper, WantedConstraints)
-> TcM (HsWrapper, WantedConstraints)
forall a b. (a -> b) -> a -> b
$
TcM HsWrapper -> TcM (HsWrapper, WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints (TcM HsWrapper -> TcM (HsWrapper, WantedConstraints))
-> TcM HsWrapper -> TcM (HsWrapper, WantedConstraints)
forall a b. (a -> b) -> a -> b
$
UserTypeCtxt -> Type -> Type -> TcM HsWrapper
tcSubType_NC UserTypeCtxt
ctxt Type
ty Type
ty
; Type -> WantedConstraints -> TcM ()
simplifyAmbiguityCheck Type
ty WantedConstraints
wanted
; String -> SDoc -> TcM ()
traceTc "Done ambiguity check for" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty) }
| Bool
otherwise
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
mk_msg :: Bool -> SDoc
mk_msg allow_ambiguous :: Bool
allow_ambiguous
= [SDoc] -> SDoc
vcat [ String -> SDoc
text "In the ambiguity check for" SDoc -> SDoc -> SDoc
<+> SDoc
what
, Bool -> SDoc -> SDoc
ppUnless Bool
allow_ambiguous SDoc
ambig_msg ]
ambig_msg :: SDoc
ambig_msg = String -> SDoc
text "To defer the ambiguity check to use sites, enable AllowAmbiguousTypes"
what :: SDoc
what | Just n :: Name
n <- UserTypeCtxt -> Maybe Name
isSigMaybe UserTypeCtxt
ctxt = SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
n)
| Bool
otherwise = UserTypeCtxt -> SDoc
pprUserTypeCtxt UserTypeCtxt
ctxt
wantAmbiguityCheck :: UserTypeCtxt -> Bool
wantAmbiguityCheck :: UserTypeCtxt -> Bool
wantAmbiguityCheck ctxt :: UserTypeCtxt
ctxt
= case UserTypeCtxt
ctxt of
GhciCtxt {} -> Bool
False
TySynCtxt {} -> Bool
False
TypeAppCtxt -> Bool
False
_ -> Bool
True
checkUserTypeError :: Type -> TcM ()
checkUserTypeError :: Type -> TcM ()
checkUserTypeError = Type -> TcM ()
check
where
check :: Type -> TcM ()
check ty :: Type
ty
| Just msg :: Type
msg <- Type -> Maybe Type
userTypeError_maybe Type
ty = Type -> TcM ()
forall b. Type -> IOEnv (Env TcGblEnv TcLclEnv) b
fail_with Type
msg
| Just (_,ts :: [Type]
ts) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty = (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Type -> TcM ()
check [Type]
ts
| Just (t1 :: Type
t1,t2 :: Type
t2) <- Type -> Maybe (Type, Type)
splitAppTy_maybe Type
ty = Type -> TcM ()
check Type
t1 TcM () -> TcM () -> TcM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Type -> TcM ()
check Type
t2
| Just (_,t1 :: Type
t1) <- Type -> Maybe (TyCoVar, Type)
splitForAllTy_maybe Type
ty = Type -> TcM ()
check Type
t1
| Bool
otherwise = () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
fail_with :: Type -> IOEnv (Env TcGblEnv TcLclEnv) b
fail_with msg :: Type
msg = do { TidyEnv
env0 <- TcM TidyEnv
tcInitTidyEnv
; let (env1 :: TidyEnv
env1, tidy_msg :: Type
tidy_msg) = TidyEnv -> Type -> (TidyEnv, Type)
tidyOpenType TidyEnv
env0 Type
msg
; (TidyEnv, SDoc) -> IOEnv (Env TcGblEnv TcLclEnv) b
forall a. (TidyEnv, SDoc) -> TcM a
failWithTcM (TidyEnv
env1, Type -> SDoc
pprUserTypeErrorTy Type
tidy_msg) }
checkValidType :: UserTypeCtxt -> Type -> TcM ()
checkValidType :: UserTypeCtxt -> Type -> TcM ()
checkValidType ctxt :: UserTypeCtxt
ctxt ty :: Type
ty
= do { String -> SDoc -> TcM ()
traceTc "checkValidType" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "::" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
ty))
; Bool
rankn_flag <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.RankNTypes
; Bool
impred_flag <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.ImpredicativeTypes
; let gen_rank :: Rank -> Rank
gen_rank :: Rank -> Rank
gen_rank r :: Rank
r | Bool
rankn_flag = Rank
ArbitraryRank
| Bool
otherwise = Rank
r
rank1 :: Rank
rank1 = Rank -> Rank
gen_rank Rank
r1
rank0 :: Rank
rank0 = Rank -> Rank
gen_rank Rank
r0
r0 :: Rank
r0 = Rank
rankZeroMonoType
r1 :: Rank
r1 = Bool -> Rank -> Rank
LimitedRank Bool
True Rank
r0
rank :: Rank
rank
= case UserTypeCtxt
ctxt of
DefaultDeclCtxt-> Rank
MustBeMonoType
ResSigCtxt -> Rank
MustBeMonoType
PatSigCtxt -> Rank
rank0
RuleSigCtxt _ -> Rank
rank1
TySynCtxt _ -> Rank
rank0
ExprSigCtxt -> Rank
rank1
KindSigCtxt -> Rank
rank1
TypeAppCtxt | Bool
impred_flag -> Rank
ArbitraryRank
| Bool
otherwise -> Rank
tyConArgMonoType
FunSigCtxt {} -> Rank
rank1
InfSigCtxt _ -> Rank
ArbitraryRank
ConArgCtxt _ -> Rank
rank1
PatSynCtxt _ -> Rank
rank1
ForSigCtxt _ -> Rank
rank1
SpecInstCtxt -> Rank
rank1
ThBrackCtxt -> Rank
rank1
GhciCtxt {} -> Rank
ArbitraryRank
TyVarBndrKindCtxt _ -> Rank
rank0
DataKindCtxt _ -> Rank
rank1
TySynKindCtxt _ -> Rank
rank1
TyFamResKindCtxt _ -> Rank
rank1
_ -> String -> Rank
forall a. String -> a
panic "checkValidType"
; TidyEnv
env <- [TyCoVar] -> TcM TidyEnv
tcInitOpenTidyEnv (Type -> [TyCoVar]
tyCoVarsOfTypeList Type
ty)
; ExpandMode
expand <- TcM ExpandMode
initialExpandMode
; let ve :: ValidityEnv
ve = ValidityEnv :: TidyEnv -> UserTypeCtxt -> Rank -> ExpandMode -> ValidityEnv
ValidityEnv{ ve_tidy_env :: TidyEnv
ve_tidy_env = TidyEnv
env, ve_ctxt :: UserTypeCtxt
ve_ctxt = UserTypeCtxt
ctxt
, ve_rank :: Rank
ve_rank = Rank
rank, ve_expand :: ExpandMode
ve_expand = ExpandMode
expand }
; TcM () -> TcM ()
forall r. TcM r -> TcM r
checkNoErrs (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
do { ValidityEnv -> Type -> TcM ()
check_type ValidityEnv
ve Type
ty
; Type -> TcM ()
checkUserTypeError Type
ty
; String -> SDoc -> TcM ()
traceTc "done ct" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty) }
; UserTypeCtxt -> Type -> TcM ()
checkAmbiguity UserTypeCtxt
ctxt Type
ty
; String -> SDoc -> TcM ()
traceTc "checkValidType done" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "::" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
ty)) }
checkValidMonoType :: Type -> TcM ()
checkValidMonoType :: Type -> TcM ()
checkValidMonoType ty :: Type
ty
= do { TidyEnv
env <- [TyCoVar] -> TcM TidyEnv
tcInitOpenTidyEnv (Type -> [TyCoVar]
tyCoVarsOfTypeList Type
ty)
; ExpandMode
expand <- TcM ExpandMode
initialExpandMode
; let ve :: ValidityEnv
ve = ValidityEnv :: TidyEnv -> UserTypeCtxt -> Rank -> ExpandMode -> ValidityEnv
ValidityEnv{ ve_tidy_env :: TidyEnv
ve_tidy_env = TidyEnv
env, ve_ctxt :: UserTypeCtxt
ve_ctxt = UserTypeCtxt
SigmaCtxt
, ve_rank :: Rank
ve_rank = Rank
MustBeMonoType, ve_expand :: ExpandMode
ve_expand = ExpandMode
expand }
; ValidityEnv -> Type -> TcM ()
check_type ValidityEnv
ve Type
ty }
checkTySynRhs :: UserTypeCtxt -> TcType -> TcM ()
checkTySynRhs :: UserTypeCtxt -> Type -> TcM ()
checkTySynRhs ctxt :: UserTypeCtxt
ctxt ty :: Type
ty
| Type -> Bool
tcReturnsConstraintKind Type
actual_kind
= do { Bool
ck <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.ConstraintKinds
; if Bool
ck
then Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Type -> Bool
tcIsConstraintKind Type
actual_kind)
(do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; ExpandMode
expand <- TcM ExpandMode
initialExpandMode
; TidyEnv -> DynFlags -> UserTypeCtxt -> ExpandMode -> Type -> TcM ()
check_pred_ty TidyEnv
emptyTidyEnv DynFlags
dflags UserTypeCtxt
ctxt ExpandMode
expand Type
ty })
else (TidyEnv, SDoc) -> TcM ()
addErrTcM (TidyEnv -> Type -> (TidyEnv, SDoc)
constraintSynErr TidyEnv
emptyTidyEnv Type
actual_kind) }
| Bool
otherwise
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
actual_kind :: Type
actual_kind = HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
ty
data Rank = ArbitraryRank
| LimitedRank
Bool
Rank
| MonoType SDoc
| MustBeMonoType
instance Outputable Rank where
ppr :: Rank -> SDoc
ppr ArbitraryRank = String -> SDoc
text "ArbitraryRank"
ppr (LimitedRank top_forall_ok :: Bool
top_forall_ok r :: Rank
r)
= String -> SDoc
text "LimitedRank" SDoc -> SDoc -> SDoc
<+> Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
top_forall_ok
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens (Rank -> SDoc
forall a. Outputable a => a -> SDoc
ppr Rank
r)
ppr (MonoType msg :: SDoc
msg) = String -> SDoc
text "MonoType" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens SDoc
msg
ppr MustBeMonoType = String -> SDoc
text "MustBeMonoType"
rankZeroMonoType, tyConArgMonoType, synArgMonoType, constraintMonoType :: Rank
rankZeroMonoType :: Rank
rankZeroMonoType = SDoc -> Rank
MonoType (String -> SDoc
text "Perhaps you intended to use RankNTypes")
tyConArgMonoType :: Rank
tyConArgMonoType = SDoc -> Rank
MonoType (String -> SDoc
text "GHC doesn't yet support impredicative polymorphism")
synArgMonoType :: Rank
synArgMonoType = SDoc -> Rank
MonoType (String -> SDoc
text "Perhaps you intended to use LiberalTypeSynonyms")
constraintMonoType :: Rank
constraintMonoType = SDoc -> Rank
MonoType ([SDoc] -> SDoc
vcat [ String -> SDoc
text "A constraint must be a monotype"
, String -> SDoc
text "Perhaps you intended to use QuantifiedConstraints" ])
funArgResRank :: Rank -> (Rank, Rank)
funArgResRank :: Rank -> (Rank, Rank)
funArgResRank (LimitedRank _ arg_rank :: Rank
arg_rank) = (Rank
arg_rank, Bool -> Rank -> Rank
LimitedRank (Rank -> Bool
forAllAllowed Rank
arg_rank) Rank
arg_rank)
funArgResRank other_rank :: Rank
other_rank = (Rank
other_rank, Rank
other_rank)
forAllAllowed :: Rank -> Bool
forAllAllowed :: Rank -> Bool
forAllAllowed ArbitraryRank = Bool
True
forAllAllowed (LimitedRank forall_ok :: Bool
forall_ok _) = Bool
forall_ok
forAllAllowed _ = Bool
False
constraintsAllowed :: UserTypeCtxt -> Bool
constraintsAllowed :: UserTypeCtxt -> Bool
constraintsAllowed (TyVarBndrKindCtxt {}) = Bool
False
constraintsAllowed (DataKindCtxt {}) = Bool
False
constraintsAllowed (TySynKindCtxt {}) = Bool
False
constraintsAllowed (TyFamResKindCtxt {}) = Bool
False
constraintsAllowed _ = Bool
True
data ExpandMode
= Expand
| NoExpand
| Both
instance Outputable ExpandMode where
ppr :: ExpandMode -> SDoc
ppr e :: ExpandMode
e = String -> SDoc
text (String -> SDoc) -> String -> SDoc
forall a b. (a -> b) -> a -> b
$ case ExpandMode
e of
Expand -> "Expand"
NoExpand -> "NoExpand"
Both -> "Both"
initialExpandMode :: TcM ExpandMode
initialExpandMode :: TcM ExpandMode
initialExpandMode = do
Bool
liberal_flag <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.LiberalTypeSynonyms
ExpandMode -> TcM ExpandMode
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpandMode -> TcM ExpandMode) -> ExpandMode -> TcM ExpandMode
forall a b. (a -> b) -> a -> b
$ if Bool
liberal_flag then ExpandMode
Expand else ExpandMode
Both
data ValidityEnv = ValidityEnv
{ ValidityEnv -> TidyEnv
ve_tidy_env :: TidyEnv
, ValidityEnv -> UserTypeCtxt
ve_ctxt :: UserTypeCtxt
, ValidityEnv -> Rank
ve_rank :: Rank
, ValidityEnv -> ExpandMode
ve_expand :: ExpandMode }
instance Outputable ValidityEnv where
ppr :: ValidityEnv -> SDoc
ppr (ValidityEnv{ ve_tidy_env :: ValidityEnv -> TidyEnv
ve_tidy_env = TidyEnv
env, ve_ctxt :: ValidityEnv -> UserTypeCtxt
ve_ctxt = UserTypeCtxt
ctxt
, ve_rank :: ValidityEnv -> Rank
ve_rank = Rank
rank, ve_expand :: ValidityEnv -> ExpandMode
ve_expand = ExpandMode
expand }) =
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "ValidityEnv")
2 ([SDoc] -> SDoc
vcat [ String -> SDoc
text "ve_tidy_env" SDoc -> SDoc -> SDoc
<+> TidyEnv -> SDoc
forall a. Outputable a => a -> SDoc
ppr TidyEnv
env
, String -> SDoc
text "ve_ctxt" SDoc -> SDoc -> SDoc
<+> UserTypeCtxt -> SDoc
pprUserTypeCtxt UserTypeCtxt
ctxt
, String -> SDoc
text "ve_rank" SDoc -> SDoc -> SDoc
<+> Rank -> SDoc
forall a. Outputable a => a -> SDoc
ppr Rank
rank
, String -> SDoc
text "ve_expand" SDoc -> SDoc -> SDoc
<+> ExpandMode -> SDoc
forall a. Outputable a => a -> SDoc
ppr ExpandMode
expand ])
check_type :: ValidityEnv -> Type -> TcM ()
check_type :: ValidityEnv -> Type -> TcM ()
check_type _ (TyVarTy _) = () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
check_type ve :: ValidityEnv
ve (AppTy ty1 :: Type
ty1 ty2 :: Type
ty2)
= do { ValidityEnv -> Type -> TcM ()
check_type ValidityEnv
ve Type
ty1
; Bool -> ValidityEnv -> Type -> TcM ()
check_arg_type Bool
False ValidityEnv
ve Type
ty2 }
check_type ve :: ValidityEnv
ve ty :: Type
ty@(TyConApp tc :: TyCon
tc tys :: [Type]
tys)
| TyCon -> Bool
isTypeSynonymTyCon TyCon
tc Bool -> Bool -> Bool
|| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
= ValidityEnv -> Type -> TyCon -> [Type] -> TcM ()
check_syn_tc_app ValidityEnv
ve Type
ty TyCon
tc [Type]
tys
| TyCon -> Bool
isUnboxedTupleTyCon TyCon
tc = ValidityEnv -> Type -> [Type] -> TcM ()
check_ubx_tuple ValidityEnv
ve Type
ty [Type]
tys
| Bool
otherwise = (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Bool -> ValidityEnv -> Type -> TcM ()
check_arg_type Bool
False ValidityEnv
ve) [Type]
tys
check_type _ (LitTy {}) = () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
check_type ve :: ValidityEnv
ve (CastTy ty :: Type
ty _) = ValidityEnv -> Type -> TcM ()
check_type ValidityEnv
ve Type
ty
check_type ve :: ValidityEnv
ve@(ValidityEnv{ ve_tidy_env :: ValidityEnv -> TidyEnv
ve_tidy_env = TidyEnv
env, ve_ctxt :: ValidityEnv -> UserTypeCtxt
ve_ctxt = UserTypeCtxt
ctxt
, ve_rank :: ValidityEnv -> Rank
ve_rank = Rank
rank, ve_expand :: ValidityEnv -> ExpandMode
ve_expand = ExpandMode
expand }) ty :: Type
ty
| Bool -> Bool
not ([TyVarBinder] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyVarBinder]
tvbs Bool -> Bool -> Bool
&& [Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
theta)
= do { String -> SDoc -> TcM ()
traceTc "check_type" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty SDoc -> SDoc -> SDoc
$$ Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Rank -> Bool
forAllAllowed Rank
rank))
; Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM (Rank -> Bool
forAllAllowed Rank
rank) (TidyEnv -> Rank -> Type -> (TidyEnv, SDoc)
forAllTyErr TidyEnv
env Rank
rank Type
ty)
; Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM ([Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
theta Bool -> Bool -> Bool
|| UserTypeCtxt -> Bool
constraintsAllowed UserTypeCtxt
ctxt)
(TidyEnv -> Type -> (TidyEnv, SDoc)
constraintTyErr TidyEnv
env Type
ty)
; TidyEnv -> UserTypeCtxt -> ExpandMode -> [Type] -> TcM ()
check_valid_theta TidyEnv
env' UserTypeCtxt
SigmaCtxt ExpandMode
expand [Type]
theta
; ValidityEnv -> Type -> TcM ()
check_type (ValidityEnv
ve{ve_tidy_env :: TidyEnv
ve_tidy_env = TidyEnv
env'}) Type
tau
; Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM (Bool -> Bool
not ((TyCoVar -> Bool) -> [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (TyCoVar -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
phi_kind) [TyCoVar]
tvs))
(TidyEnv -> Type -> Type -> (TidyEnv, SDoc)
forAllEscapeErr TidyEnv
env' Type
ty Type
tau_kind)
}
where
(tvbs :: [TyVarBinder]
tvbs, phi :: Type
phi) = Type -> ([TyVarBinder], Type)
tcSplitForAllVarBndrs Type
ty
(theta :: [Type]
theta, tau :: Type
tau) = Type -> ([Type], Type)
tcSplitPhiTy Type
phi
tvs :: [TyCoVar]
tvs = [TyVarBinder] -> [TyCoVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyVarBinder]
tvbs
(env' :: TidyEnv
env', _) = TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
tidyVarBndrs TidyEnv
env [TyCoVar]
tvs
tau_kind :: Type
tau_kind = HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
tau
phi_kind :: Type
phi_kind | [Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
theta = Type
tau_kind
| Bool
otherwise = Type
liftedTypeKind
check_type (ve :: ValidityEnv
ve@ValidityEnv{ve_rank :: ValidityEnv -> Rank
ve_rank = Rank
rank}) (FunTy arg_ty :: Type
arg_ty res_ty :: Type
res_ty)
= do { ValidityEnv -> Type -> TcM ()
check_type (ValidityEnv
ve{ve_rank :: Rank
ve_rank = Rank
arg_rank}) Type
arg_ty
; ValidityEnv -> Type -> TcM ()
check_type (ValidityEnv
ve{ve_rank :: Rank
ve_rank = Rank
res_rank}) Type
res_ty }
where
(arg_rank :: Rank
arg_rank, res_rank :: Rank
res_rank) = Rank -> (Rank, Rank)
funArgResRank Rank
rank
check_type _ ty :: Type
ty = String -> SDoc -> TcM ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic "check_type" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
check_syn_tc_app :: ValidityEnv
-> KindOrType -> TyCon -> [KindOrType] -> TcM ()
check_syn_tc_app :: ValidityEnv -> Type -> TyCon -> [Type] -> TcM ()
check_syn_tc_app (ve :: ValidityEnv
ve@ValidityEnv{ ve_ctxt :: ValidityEnv -> UserTypeCtxt
ve_ctxt = UserTypeCtxt
ctxt, ve_expand :: ValidityEnv -> ExpandMode
ve_expand = ExpandMode
expand })
ty :: Type
ty tc :: TyCon
tc tys :: [Type]
tys
| [Type]
tys [Type] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthAtLeast` Int
tc_arity
= case ExpandMode
expand of
_ | TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
-> ExpandMode -> TcM ()
check_args_only ExpandMode
expand
Expand -> ExpandMode -> TcM ()
check_expansion_only ExpandMode
expand
NoExpand -> ExpandMode -> TcM ()
check_args_only ExpandMode
expand
Both -> ExpandMode -> TcM ()
check_args_only ExpandMode
NoExpand TcM () -> TcM () -> TcM ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ExpandMode -> TcM ()
check_expansion_only ExpandMode
Both
| GhciCtxt True <- UserTypeCtxt
ctxt
= ExpandMode -> TcM ()
check_args_only ExpandMode
expand
| Bool
otherwise
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (TyCon -> [Type] -> SDoc
tyConArityErr TyCon
tc [Type]
tys)
where
tc_arity :: Int
tc_arity = TyCon -> Int
tyConArity TyCon
tc
check_arg :: ExpandMode -> KindOrType -> TcM ()
check_arg :: ExpandMode -> Type -> TcM ()
check_arg expand :: ExpandMode
expand =
Bool -> ValidityEnv -> Type -> TcM ()
check_arg_type (TyCon -> Bool
isTypeSynonymTyCon TyCon
tc) (ValidityEnv
ve{ve_expand :: ExpandMode
ve_expand = ExpandMode
expand})
check_args_only, check_expansion_only :: ExpandMode -> TcM ()
check_args_only :: ExpandMode -> TcM ()
check_args_only expand :: ExpandMode
expand = (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (ExpandMode -> Type -> TcM ()
check_arg ExpandMode
expand) [Type]
tys
check_expansion_only :: ExpandMode -> TcM ()
check_expansion_only expand :: ExpandMode
expand =
case Type -> Maybe Type
tcView Type
ty of
Just ty' :: Type
ty' -> let syn_tc :: TyCon
syn_tc = (TyCon, [Type]) -> TyCon
forall a b. (a, b) -> a
fst ((TyCon, [Type]) -> TyCon) -> (TyCon, [Type]) -> TyCon
forall a b. (a -> b) -> a -> b
$ HasCallStack => Type -> (TyCon, [Type])
Type -> (TyCon, [Type])
tcRepSplitTyConApp Type
ty
err_ctxt :: SDoc
err_ctxt = String -> SDoc
text "In the expansion of type synonym"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
syn_tc)
in SDoc -> TcM () -> TcM ()
forall a. SDoc -> TcM a -> TcM a
addErrCtxt SDoc
err_ctxt (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
ValidityEnv -> Type -> TcM ()
check_type (ValidityEnv
ve{ve_expand :: ExpandMode
ve_expand = ExpandMode
expand}) Type
ty'
Nothing -> String -> SDoc -> TcM ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic "check_syn_tc_app" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
check_ubx_tuple :: ValidityEnv -> KindOrType -> [KindOrType] -> TcM ()
check_ubx_tuple :: ValidityEnv -> Type -> [Type] -> TcM ()
check_ubx_tuple (ve :: ValidityEnv
ve@ValidityEnv{ve_tidy_env :: ValidityEnv -> TidyEnv
ve_tidy_env = TidyEnv
env}) ty :: Type
ty tys :: [Type]
tys
= do { Bool
ub_tuples_allowed <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.UnboxedTuples
; Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM Bool
ub_tuples_allowed (TidyEnv -> Type -> (TidyEnv, SDoc)
ubxArgTyErr TidyEnv
env Type
ty)
; Bool
impred <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.ImpredicativeTypes
; let rank' :: Rank
rank' = if Bool
impred then Rank
ArbitraryRank else Rank
tyConArgMonoType
; (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (ValidityEnv -> Type -> TcM ()
check_type (ValidityEnv
ve{ve_rank :: Rank
ve_rank = Rank
rank'})) [Type]
tys }
check_arg_type
:: Bool
-> ValidityEnv -> KindOrType -> TcM ()
check_arg_type :: Bool -> ValidityEnv -> Type -> TcM ()
check_arg_type _ _ (CoercionTy {}) = () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
check_arg_type type_syn :: Bool
type_syn (ve :: ValidityEnv
ve@ValidityEnv{ve_ctxt :: ValidityEnv -> UserTypeCtxt
ve_ctxt = UserTypeCtxt
ctxt, ve_rank :: ValidityEnv -> Rank
ve_rank = Rank
rank}) ty :: Type
ty
= do { Bool
impred <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.ImpredicativeTypes
; let rank' :: Rank
rank' = case Rank
rank of
_ | Bool
type_syn -> Rank
synArgMonoType
MustBeMonoType -> Rank
MustBeMonoType
_other :: Rank
_other | Bool
impred -> Rank
ArbitraryRank
| Bool
otherwise -> Rank
tyConArgMonoType
ctxt' :: UserTypeCtxt
ctxt' :: UserTypeCtxt
ctxt'
| GhciCtxt _ <- UserTypeCtxt
ctxt = Bool -> UserTypeCtxt
GhciCtxt Bool
False
| Bool
otherwise = UserTypeCtxt
ctxt
; ValidityEnv -> Type -> TcM ()
check_type (ValidityEnv
ve{ve_ctxt :: UserTypeCtxt
ve_ctxt = UserTypeCtxt
ctxt', ve_rank :: Rank
ve_rank = Rank
rank'}) Type
ty }
forAllTyErr :: TidyEnv -> Rank -> Type -> (TidyEnv, SDoc)
forAllTyErr :: TidyEnv -> Rank -> Type -> (TidyEnv, SDoc)
forAllTyErr env :: TidyEnv
env rank :: Rank
rank ty :: Type
ty
= ( TidyEnv
env
, [SDoc] -> SDoc
vcat [ SDoc -> Int -> SDoc -> SDoc
hang SDoc
herald 2 (TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
ty)
, SDoc
suggestion ] )
where
(tvs :: [TyCoVar]
tvs, _theta :: [Type]
_theta, _tau :: Type
_tau) = Type -> ([TyCoVar], [Type], Type)
tcSplitSigmaTy Type
ty
herald :: SDoc
herald | [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
tvs = String -> SDoc
text "Illegal qualified type:"
| Bool
otherwise = String -> SDoc
text "Illegal polymorphic type:"
suggestion :: SDoc
suggestion = case Rank
rank of
LimitedRank {} -> String -> SDoc
text "Perhaps you intended to use RankNTypes"
MonoType d :: SDoc
d -> SDoc
d
_ -> SDoc
Outputable.empty
forAllEscapeErr :: TidyEnv -> Type -> Kind -> (TidyEnv, SDoc)
forAllEscapeErr :: TidyEnv -> Type -> Type -> (TidyEnv, SDoc)
forAllEscapeErr env :: TidyEnv
env ty :: Type
ty tau_kind :: Type
tau_kind
= ( TidyEnv
env
, SDoc -> Int -> SDoc -> SDoc
hang ([SDoc] -> SDoc
vcat [ String -> SDoc
text "Quantified type's kind mentions quantified type variable"
, String -> SDoc
text "(skolem escape)" ])
2 ([SDoc] -> SDoc
vcat [ String -> SDoc
text " type:" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
ty
, String -> SDoc
text "of kind:" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
tau_kind ]) )
ubxArgTyErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
ubxArgTyErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
ubxArgTyErr env :: TidyEnv
env ty :: Type
ty
= ( TidyEnv
env, [SDoc] -> SDoc
vcat [ [SDoc] -> SDoc
sep [ String -> SDoc
text "Illegal unboxed tuple type as function argument:"
, TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
ty ]
, String -> SDoc
text "Perhaps you intended to use UnboxedTuples" ] )
constraintTyErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
constraintTyErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
constraintTyErr env :: TidyEnv
env ty :: Type
ty
= (TidyEnv
env, String -> SDoc
text "Illegal constraint in a kind:" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
ty)
checkValidTheta :: UserTypeCtxt -> ThetaType -> TcM ()
checkValidTheta :: UserTypeCtxt -> [Type] -> TcM ()
checkValidTheta ctxt :: UserTypeCtxt
ctxt theta :: [Type]
theta
= (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcM () -> TcM ()
forall a. (TidyEnv -> TcM (TidyEnv, SDoc)) -> TcM a -> TcM a
addErrCtxtM (UserTypeCtxt -> [Type] -> TidyEnv -> TcM (TidyEnv, SDoc)
checkThetaCtxt UserTypeCtxt
ctxt [Type]
theta) (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
do { TidyEnv
env <- [TyCoVar] -> TcM TidyEnv
tcInitOpenTidyEnv ([Type] -> [TyCoVar]
tyCoVarsOfTypesList [Type]
theta)
; ExpandMode
expand <- TcM ExpandMode
initialExpandMode
; TidyEnv -> UserTypeCtxt -> ExpandMode -> [Type] -> TcM ()
check_valid_theta TidyEnv
env UserTypeCtxt
ctxt ExpandMode
expand [Type]
theta }
check_valid_theta :: TidyEnv -> UserTypeCtxt -> ExpandMode
-> [PredType] -> TcM ()
check_valid_theta :: TidyEnv -> UserTypeCtxt -> ExpandMode -> [Type] -> TcM ()
check_valid_theta _ _ _ []
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
check_valid_theta env :: TidyEnv
env ctxt :: UserTypeCtxt
ctxt expand :: ExpandMode
expand theta :: [Type]
theta
= do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; WarnReason -> Bool -> (TidyEnv, SDoc) -> TcM ()
warnTcM (WarningFlag -> WarnReason
Reason WarningFlag
Opt_WarnDuplicateConstraints)
(WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnDuplicateConstraints DynFlags
dflags Bool -> Bool -> Bool
&& [NonEmpty Type] -> Bool
forall a. [a] -> Bool
notNull [NonEmpty Type]
dups)
(TidyEnv -> [NonEmpty Type] -> (TidyEnv, SDoc)
dupPredWarn TidyEnv
env [NonEmpty Type]
dups)
; String -> SDoc -> TcM ()
traceTc "check_valid_theta" ([Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
theta)
; (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (TidyEnv -> DynFlags -> UserTypeCtxt -> ExpandMode -> Type -> TcM ()
check_pred_ty TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt ExpandMode
expand) [Type]
theta }
where
(_,dups :: [NonEmpty Type]
dups) = (Type -> Type -> Ordering) -> [Type] -> ([Type], [NonEmpty Type])
forall a. (a -> a -> Ordering) -> [a] -> ([a], [NonEmpty a])
removeDups Type -> Type -> Ordering
nonDetCmpType [Type]
theta
check_pred_ty :: TidyEnv -> DynFlags -> UserTypeCtxt -> ExpandMode
-> PredType -> TcM ()
check_pred_ty :: TidyEnv -> DynFlags -> UserTypeCtxt -> ExpandMode -> Type -> TcM ()
check_pred_ty env :: TidyEnv
env dflags :: DynFlags
dflags ctxt :: UserTypeCtxt
ctxt expand :: ExpandMode
expand pred :: Type
pred
= do { ValidityEnv -> Type -> TcM ()
check_type ValidityEnv
ve Type
pred
; Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> TcM ()
check_pred_help Bool
False TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Type
pred }
where
rank :: Rank
rank | Extension -> DynFlags -> Bool
xopt Extension
LangExt.QuantifiedConstraints DynFlags
dflags
= Rank
ArbitraryRank
| Bool
otherwise
= Rank
constraintMonoType
ve :: ValidityEnv
ve :: ValidityEnv
ve = ValidityEnv :: TidyEnv -> UserTypeCtxt -> Rank -> ExpandMode -> ValidityEnv
ValidityEnv{ ve_tidy_env :: TidyEnv
ve_tidy_env = TidyEnv
env
, ve_ctxt :: UserTypeCtxt
ve_ctxt = UserTypeCtxt
SigmaCtxt
, ve_rank :: Rank
ve_rank = Rank
rank
, ve_expand :: ExpandMode
ve_expand = ExpandMode
expand }
check_pred_help :: Bool
-> TidyEnv
-> DynFlags -> UserTypeCtxt
-> PredType -> TcM ()
check_pred_help :: Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> TcM ()
check_pred_help under_syn :: Bool
under_syn env :: TidyEnv
env dflags :: DynFlags
dflags ctxt :: UserTypeCtxt
ctxt pred :: Type
pred
| Just pred' :: Type
pred' <- Type -> Maybe Type
tcView Type
pred
= Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> TcM ()
check_pred_help Bool
True TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Type
pred'
| Bool
otherwise
= case Type -> PredTree
classifyPredType Type
pred of
ClassPred cls :: Class
cls tys :: [Type]
tys
| Class -> Bool
isCTupleClass Class
cls -> Bool
-> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> [Type] -> TcM ()
check_tuple_pred Bool
under_syn TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Type
pred [Type]
tys
| Bool
otherwise -> TidyEnv
-> DynFlags -> UserTypeCtxt -> Type -> Class -> [Type] -> TcM ()
check_class_pred TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Type
pred Class
cls [Type]
tys
EqPred NomEq _ _ ->
TidyEnv -> DynFlags -> Type -> TcM ()
check_eq_pred TidyEnv
env DynFlags
dflags Type
pred
EqPred ReprEq _ _ ->
() -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
ForAllPred _ theta :: [Type]
theta head :: Type
head -> TidyEnv
-> DynFlags -> UserTypeCtxt -> Type -> [Type] -> Type -> TcM ()
check_quant_pred TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Type
pred [Type]
theta Type
head
IrredPred {} -> Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> TcM ()
check_irred_pred Bool
under_syn TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Type
pred
check_eq_pred :: TidyEnv -> DynFlags -> PredType -> TcM ()
check_eq_pred :: TidyEnv -> DynFlags -> Type -> TcM ()
check_eq_pred env :: TidyEnv
env dflags :: DynFlags
dflags pred :: Type
pred
=
Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM (Extension -> DynFlags -> Bool
xopt Extension
LangExt.TypeFamilies DynFlags
dflags
Bool -> Bool -> Bool
|| Extension -> DynFlags -> Bool
xopt Extension
LangExt.GADTs DynFlags
dflags)
(TidyEnv -> Type -> (TidyEnv, SDoc)
eqPredTyErr TidyEnv
env Type
pred)
check_quant_pred :: TidyEnv -> DynFlags -> UserTypeCtxt
-> PredType -> ThetaType -> PredType -> TcM ()
check_quant_pred :: TidyEnv
-> DynFlags -> UserTypeCtxt -> Type -> [Type] -> Type -> TcM ()
check_quant_pred env :: TidyEnv
env dflags :: DynFlags
dflags _ctxt :: UserTypeCtxt
_ctxt pred :: Type
pred theta :: [Type]
theta head_pred :: Type
head_pred
= SDoc -> TcM () -> TcM ()
forall a. SDoc -> TcM a -> TcM a
addErrCtxt (String -> SDoc
text "In the quantified constraint" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred)) (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
do {
case Type -> PredTree
classifyPredType Type
head_pred of
ClassPred cls :: Class
cls tys :: [Type]
tys -> UserTypeCtxt -> Class -> [Type] -> TcM ()
checkValidInstHead UserTypeCtxt
SigmaCtxt Class
cls [Type]
tys
IrredPred {} | Type -> Bool
hasTyVarHead Type
head_pred
-> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
_ -> (TidyEnv, SDoc) -> TcM ()
forall a. (TidyEnv, SDoc) -> TcM a
failWithTcM (TidyEnv -> Type -> (TidyEnv, SDoc)
badQuantHeadErr TidyEnv
env Type
pred)
; Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Extension -> DynFlags -> Bool
xopt Extension
LangExt.UndecidableInstances DynFlags
dflags) (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
[Type] -> Type -> TcM ()
checkInstTermination [Type]
theta Type
head_pred
}
check_tuple_pred :: Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> PredType -> [PredType] -> TcM ()
check_tuple_pred :: Bool
-> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> [Type] -> TcM ()
check_tuple_pred under_syn :: Bool
under_syn env :: TidyEnv
env dflags :: DynFlags
dflags ctxt :: UserTypeCtxt
ctxt pred :: Type
pred ts :: [Type]
ts
= do {
Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM (Bool
under_syn Bool -> Bool -> Bool
|| Extension -> DynFlags -> Bool
xopt Extension
LangExt.ConstraintKinds DynFlags
dflags)
(TidyEnv -> Type -> (TidyEnv, SDoc)
predTupleErr TidyEnv
env Type
pred)
; (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> TcM ()
check_pred_help Bool
under_syn TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt) [Type]
ts }
check_irred_pred :: Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> PredType -> TcM ()
check_irred_pred :: Bool -> TidyEnv -> DynFlags -> UserTypeCtxt -> Type -> TcM ()
check_irred_pred under_syn :: Bool
under_syn env :: TidyEnv
env dflags :: DynFlags
dflags ctxt :: UserTypeCtxt
ctxt pred :: Type
pred
= do {
Bool -> (TidyEnv, SDoc) -> TcM ()
failIfTcM (Bool -> Bool
not Bool
under_syn Bool -> Bool -> Bool
&& Bool -> Bool
not (Extension -> DynFlags -> Bool
xopt Extension
LangExt.ConstraintKinds DynFlags
dflags)
Bool -> Bool -> Bool
&& Type -> Bool
hasTyVarHead Type
pred)
(TidyEnv -> Type -> (TidyEnv, SDoc)
predIrredErr TidyEnv
env Type
pred)
; Bool -> (TidyEnv, SDoc) -> TcM ()
failIfTcM (UserTypeCtxt -> Bool
is_superclass UserTypeCtxt
ctxt
Bool -> Bool -> Bool
&& Bool -> Bool
not (Extension -> DynFlags -> Bool
xopt Extension
LangExt.UndecidableInstances DynFlags
dflags)
Bool -> Bool -> Bool
&& Type -> Bool
has_tyfun_head Type
pred)
(TidyEnv -> Type -> (TidyEnv, SDoc)
predSuperClassErr TidyEnv
env Type
pred) }
where
is_superclass :: UserTypeCtxt -> Bool
is_superclass ctxt :: UserTypeCtxt
ctxt = case UserTypeCtxt
ctxt of { ClassSCCtxt _ -> Bool
True; _ -> Bool
False }
has_tyfun_head :: Type -> Bool
has_tyfun_head ty :: Type
ty
= case HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe Type
ty of
Just (tc :: TyCon
tc, _) -> TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
Nothing -> Bool
False
check_class_pred :: TidyEnv -> DynFlags -> UserTypeCtxt
-> PredType -> Class -> [TcType] -> TcM ()
check_class_pred :: TidyEnv
-> DynFlags -> UserTypeCtxt -> Type -> Class -> [Type] -> TcM ()
check_class_pred env :: TidyEnv
env dflags :: DynFlags
dflags ctxt :: UserTypeCtxt
ctxt pred :: Type
pred cls :: Class
cls tys :: [Type]
tys
| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
heqTyConKey
Bool -> Bool -> Bool
|| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqTyConKey
=
TidyEnv -> DynFlags -> Type -> TcM ()
check_eq_pred TidyEnv
env DynFlags
dflags Type
pred
| Class -> Bool
isIPClass Class
cls
= do { TcM ()
check_arity
; Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM (UserTypeCtxt -> Bool
okIPCtxt UserTypeCtxt
ctxt) (TidyEnv -> Type -> (TidyEnv, SDoc)
badIPPred TidyEnv
env Type
pred) }
| Bool
otherwise
= do { TcM ()
check_arity
; TidyEnv -> DynFlags -> UserTypeCtxt -> Class -> [Type] -> TcM ()
checkSimplifiableClassConstraint TidyEnv
env DynFlags
dflags UserTypeCtxt
ctxt Class
cls [Type]
tys
; Bool -> (TidyEnv, SDoc) -> TcM ()
checkTcM Bool
arg_tys_ok (TidyEnv -> Type -> (TidyEnv, SDoc)
predTyVarErr TidyEnv
env Type
pred) }
where
check_arity :: TcM ()
check_arity = Bool -> SDoc -> TcM ()
checkTc ([Type]
tys [Type] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthIs` Class -> Int
classArity Class
cls)
(TyCon -> [Type] -> SDoc
tyConArityErr (Class -> TyCon
classTyCon Class
cls) [Type]
tys)
flexible_contexts :: Bool
flexible_contexts = Extension -> DynFlags -> Bool
xopt Extension
LangExt.FlexibleContexts DynFlags
dflags
undecidable_ok :: Bool
undecidable_ok = Extension -> DynFlags -> Bool
xopt Extension
LangExt.UndecidableInstances DynFlags
dflags
arg_tys_ok :: Bool
arg_tys_ok = case UserTypeCtxt
ctxt of
SpecInstCtxt -> Bool
True
InstDeclCtxt {} -> Bool -> Class -> [Type] -> Bool
checkValidClsArgs (Bool
flexible_contexts Bool -> Bool -> Bool
|| Bool
undecidable_ok) Class
cls [Type]
tys
_ -> Bool -> Class -> [Type] -> Bool
checkValidClsArgs Bool
flexible_contexts Class
cls [Type]
tys
checkSimplifiableClassConstraint :: TidyEnv -> DynFlags -> UserTypeCtxt
-> Class -> [TcType] -> TcM ()
checkSimplifiableClassConstraint :: TidyEnv -> DynFlags -> UserTypeCtxt -> Class -> [Type] -> TcM ()
checkSimplifiableClassConstraint env :: TidyEnv
env dflags :: DynFlags
dflags ctxt :: UserTypeCtxt
ctxt cls :: Class
cls tys :: [Type]
tys
| Bool -> Bool
not (WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnSimplifiableClassConstraints DynFlags
dflags)
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Extension -> DynFlags -> Bool
xopt Extension
LangExt.MonoLocalBinds DynFlags
dflags
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| DataTyCtxt {} <- UserTypeCtxt
ctxt
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
coercibleTyConKey
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= do { ClsInstResult
result <- DynFlags -> Bool -> Class -> [Type] -> TcM ClsInstResult
matchGlobalInst DynFlags
dflags Bool
False Class
cls [Type]
tys
; case ClsInstResult
result of
OneInst { cir_what :: ClsInstResult -> InstanceWhat
cir_what = InstanceWhat
what }
-> WarnReason -> SDoc -> TcM ()
addWarnTc (WarningFlag -> WarnReason
Reason WarningFlag
Opt_WarnSimplifiableClassConstraints)
(InstanceWhat -> SDoc
simplifiable_constraint_warn InstanceWhat
what)
_ -> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }
where
pred :: Type
pred = Class -> [Type] -> Type
mkClassPred Class
cls [Type]
tys
simplifiable_constraint_warn :: InstanceWhat -> SDoc
simplifiable_constraint_warn :: InstanceWhat -> SDoc
simplifiable_constraint_warn what :: InstanceWhat
what
= [SDoc] -> SDoc
vcat [ SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "The constraint" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
pred))
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "matches")
2 (InstanceWhat -> SDoc
ppr_what InstanceWhat
what)
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "This makes type inference for inner bindings fragile;")
2 (String -> SDoc
text "either use MonoLocalBinds, or simplify it using the instance") ]
ppr_what :: InstanceWhat -> SDoc
ppr_what BuiltinInstance = String -> SDoc
text "a built-in instance"
ppr_what LocalInstance = String -> SDoc
text "a locally-quantified instance"
ppr_what (TopLevInstance { iw_dfun_id :: InstanceWhat -> TyCoVar
iw_dfun_id = TyCoVar
dfun })
= SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "instance" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
pprSigmaType (TyCoVar -> Type
idType TyCoVar
dfun))
2 (String -> SDoc
text "--" SDoc -> SDoc -> SDoc
<+> Name -> SDoc
pprDefinedAt (TyCoVar -> Name
idName TyCoVar
dfun))
okIPCtxt :: UserTypeCtxt -> Bool
okIPCtxt :: UserTypeCtxt -> Bool
okIPCtxt (FunSigCtxt {}) = Bool
True
okIPCtxt (InfSigCtxt {}) = Bool
True
okIPCtxt ExprSigCtxt = Bool
True
okIPCtxt TypeAppCtxt = Bool
True
okIPCtxt PatSigCtxt = Bool
True
okIPCtxt ResSigCtxt = Bool
True
okIPCtxt GenSigCtxt = Bool
True
okIPCtxt (ConArgCtxt {}) = Bool
True
okIPCtxt (ForSigCtxt {}) = Bool
True
okIPCtxt ThBrackCtxt = Bool
True
okIPCtxt (GhciCtxt {}) = Bool
True
okIPCtxt SigmaCtxt = Bool
True
okIPCtxt (DataTyCtxt {}) = Bool
True
okIPCtxt (PatSynCtxt {}) = Bool
True
okIPCtxt (TySynCtxt {}) = Bool
True
okIPCtxt (KindSigCtxt {}) = Bool
False
okIPCtxt (ClassSCCtxt {}) = Bool
False
okIPCtxt (InstDeclCtxt {}) = Bool
False
okIPCtxt (SpecInstCtxt {}) = Bool
False
okIPCtxt (RuleSigCtxt {}) = Bool
False
okIPCtxt DefaultDeclCtxt = Bool
False
okIPCtxt DerivClauseCtxt = Bool
False
okIPCtxt (TyVarBndrKindCtxt {}) = Bool
False
okIPCtxt (DataKindCtxt {}) = Bool
False
okIPCtxt (TySynKindCtxt {}) = Bool
False
okIPCtxt (TyFamResKindCtxt {}) = Bool
False
checkThetaCtxt :: UserTypeCtxt -> ThetaType -> TidyEnv -> TcM (TidyEnv, SDoc)
checkThetaCtxt :: UserTypeCtxt -> [Type] -> TidyEnv -> TcM (TidyEnv, SDoc)
checkThetaCtxt ctxt :: UserTypeCtxt
ctxt theta :: [Type]
theta env :: TidyEnv
env
= (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TidyEnv
env
, [SDoc] -> SDoc
vcat [ String -> SDoc
text "In the context:" SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
pprTheta (TidyEnv -> [Type] -> [Type]
tidyTypes TidyEnv
env [Type]
theta)
, String -> SDoc
text "While checking" SDoc -> SDoc -> SDoc
<+> UserTypeCtxt -> SDoc
pprUserTypeCtxt UserTypeCtxt
ctxt ] )
eqPredTyErr, predTupleErr, predIrredErr,
predSuperClassErr, badQuantHeadErr :: TidyEnv -> PredType -> (TidyEnv, SDoc)
env :: TidyEnv
env pred :: Type
pred
= ( TidyEnv
env
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Quantified predicate must have a class or type variable head:")
2 (TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred) )
eqPredTyErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
eqPredTyErr env :: TidyEnv
env pred :: Type
pred
= ( TidyEnv
env
, String -> SDoc
text "Illegal equational constraint" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred SDoc -> SDoc -> SDoc
$$
SDoc -> SDoc
parens (String -> SDoc
text "Use GADTs or TypeFamilies to permit this") )
predTupleErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
predTupleErr env :: TidyEnv
env pred :: Type
pred
= ( TidyEnv
env
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Illegal tuple constraint:" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred)
2 (SDoc -> SDoc
parens SDoc
constraintKindsMsg) )
predIrredErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
predIrredErr env :: TidyEnv
env pred :: Type
pred
= ( TidyEnv
env
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Illegal constraint:" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred)
2 (SDoc -> SDoc
parens SDoc
constraintKindsMsg) )
predSuperClassErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
predSuperClassErr env :: TidyEnv
env pred :: Type
pred
= ( TidyEnv
env
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Illegal constraint" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred)
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "in a superclass context")
2 (SDoc -> SDoc
parens SDoc
undecidableMsg) )
predTyVarErr :: TidyEnv -> PredType -> (TidyEnv, SDoc)
predTyVarErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
predTyVarErr env :: TidyEnv
env pred :: Type
pred
= (TidyEnv
env
, [SDoc] -> SDoc
vcat [ SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Non type-variable argument")
2 (String -> SDoc
text "in the constraint:" SDoc -> SDoc -> SDoc
<+> TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred)
, SDoc -> SDoc
parens (String -> SDoc
text "Use FlexibleContexts to permit this") ])
badIPPred :: TidyEnv -> PredType -> (TidyEnv, SDoc)
badIPPred :: TidyEnv -> Type -> (TidyEnv, SDoc)
badIPPred env :: TidyEnv
env pred :: Type
pred
= ( TidyEnv
env
, String -> SDoc
text "Illegal implicit parameter" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
pred) )
constraintSynErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
constraintSynErr :: TidyEnv -> Type -> (TidyEnv, SDoc)
constraintSynErr env :: TidyEnv
env kind :: Type
kind
= ( TidyEnv
env
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Illegal constraint synonym of kind:" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env Type
kind))
2 (SDoc -> SDoc
parens SDoc
constraintKindsMsg) )
dupPredWarn :: TidyEnv -> [NE.NonEmpty PredType] -> (TidyEnv, SDoc)
dupPredWarn :: TidyEnv -> [NonEmpty Type] -> (TidyEnv, SDoc)
dupPredWarn env :: TidyEnv
env dups :: [NonEmpty Type]
dups
= ( TidyEnv
env
, String -> SDoc
text "Duplicate constraint" SDoc -> SDoc -> SDoc
<> [Type] -> SDoc
forall a. [a] -> SDoc
plural [Type]
primaryDups SDoc -> SDoc -> SDoc
<> String -> SDoc
text ":"
SDoc -> SDoc -> SDoc
<+> (Type -> SDoc) -> [Type] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas (TidyEnv -> Type -> SDoc
ppr_tidy TidyEnv
env) [Type]
primaryDups )
where
primaryDups :: [Type]
primaryDups = (NonEmpty Type -> Type) -> [NonEmpty Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map NonEmpty Type -> Type
forall a. NonEmpty a -> a
NE.head [NonEmpty Type]
dups
tyConArityErr :: TyCon -> [TcType] -> SDoc
tyConArityErr :: TyCon -> [Type] -> SDoc
tyConArityErr tc :: TyCon
tc tks :: [Type]
tks
= SDoc -> Name -> Int -> Int -> SDoc
forall a. Outputable a => SDoc -> a -> Int -> Int -> SDoc
arityErr (TyConFlavour -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> TyConFlavour
tyConFlavour TyCon
tc)) (TyCon -> Name
tyConName TyCon
tc)
Int
tc_type_arity Int
tc_type_args
where
vis_tks :: [Type]
vis_tks = TyCon -> [Type] -> [Type]
filterOutInvisibleTypes TyCon
tc [Type]
tks
tc_type_arity :: Int
tc_type_arity = (VarBndr TyCoVar TyConBndrVis -> Bool)
-> [VarBndr TyCoVar TyConBndrVis] -> Int
forall a. (a -> Bool) -> [a] -> Int
count VarBndr TyCoVar TyConBndrVis -> Bool
forall tv. VarBndr tv TyConBndrVis -> Bool
isVisibleTyConBinder (TyCon -> [VarBndr TyCoVar TyConBndrVis]
tyConBinders TyCon
tc)
tc_type_args :: Int
tc_type_args = [Type] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
vis_tks
arityErr :: Outputable a => SDoc -> a -> Int -> Int -> SDoc
arityErr :: SDoc -> a -> Int -> Int -> SDoc
arityErr what :: SDoc
what name :: a
name n :: Int
n m :: Int
m
= [SDoc] -> SDoc
hsep [ String -> SDoc
text "The" SDoc -> SDoc -> SDoc
<+> SDoc
what, SDoc -> SDoc
quotes (a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
name), String -> SDoc
text "should have",
SDoc
n_arguments SDoc -> SDoc -> SDoc
<> SDoc
comma, String -> SDoc
text "but has been given",
if Int
mInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==0 then String -> SDoc
text "none" else Int -> SDoc
int Int
m]
where
n_arguments :: SDoc
n_arguments | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = String -> SDoc
text "no arguments"
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1 = String -> SDoc
text "1 argument"
| Bool
True = [SDoc] -> SDoc
hsep [Int -> SDoc
int Int
n, String -> SDoc
text "arguments"]
checkValidInstHead :: UserTypeCtxt -> Class -> [Type] -> TcM ()
checkValidInstHead :: UserTypeCtxt -> Class -> [Type] -> TcM ()
checkValidInstHead ctxt :: UserTypeCtxt
ctxt clas :: Class
clas cls_args :: [Type]
cls_args
= do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; Bool
is_boot <- TcRnIf TcGblEnv TcLclEnv Bool
tcIsHsBootOrSig
; Bool
is_sig <- TcRnIf TcGblEnv TcLclEnv Bool
tcIsHsig
; DynFlags
-> Bool -> Bool -> UserTypeCtxt -> Class -> [Type] -> TcM ()
check_special_inst_head DynFlags
dflags Bool
is_boot Bool
is_sig UserTypeCtxt
ctxt Class
clas [Type]
cls_args
; TyCon -> [Type] -> TcM ()
checkValidTypePats (Class -> TyCon
classTyCon Class
clas) [Type]
cls_args
}
check_special_inst_head :: DynFlags -> Bool -> Bool
-> UserTypeCtxt -> Class -> [Type] -> TcM ()
check_special_inst_head :: DynFlags
-> Bool -> Bool -> UserTypeCtxt -> Class -> [Type] -> TcM ()
check_special_inst_head dflags :: DynFlags
dflags is_boot :: Bool
is_boot is_sig :: Bool
is_sig ctxt :: UserTypeCtxt
ctxt clas :: Class
clas cls_args :: [Type]
cls_args
| Class -> Bool
isAbstractClass Class
clas
, Bool -> Bool
not Bool
is_boot
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc SDoc
abstract_class_msg
| Name
clas_nm Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
typeableClassName
, Bool -> Bool
not Bool
is_sig
, Bool
hand_written_bindings
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc SDoc
rejected_class_msg
| Name
clas_nm Name -> [Name] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ Name
knownNatClassName, Name
knownSymbolClassName ]
, Bool -> Bool
not Bool
is_sig
, Bool
hand_written_bindings
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc SDoc
rejected_class_msg
| Name
clas_nm Name -> [Name] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ Name
heqTyConName, Name
eqTyConName, Name
coercibleTyConName ]
, Bool -> Bool
not Bool
quantified_constraint
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc SDoc
rejected_class_msg
| Name
clas_nm Name -> [Name] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Name]
genericClassNames
, Bool
hand_written_bindings
= do { Bool -> SDoc -> TcM ()
failIfTc (DynFlags -> Bool
safeLanguageOn DynFlags
dflags) SDoc
gen_inst_err
; Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (DynFlags -> Bool
safeInferOn DynFlags
dflags) (WarningMessages -> TcM ()
recordUnsafeInfer WarningMessages
forall a. Bag a
emptyBag) }
| Name
clas_nm Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
hasFieldClassName
= Class -> [Type] -> TcM ()
checkHasFieldInst Class
clas [Type]
cls_args
| Class -> Bool
isCTupleClass Class
clas
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc SDoc
tuple_class_msg
| Bool
check_h98_arg_shape
, Just msg :: SDoc
msg <- Maybe SDoc
mb_ty_args_msg
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (Class -> [Type] -> SDoc -> SDoc
instTypeErr Class
clas [Type]
cls_args SDoc
msg)
| Bool
otherwise
= () -> TcM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
where
clas_nm :: Name
clas_nm = Class -> Name
forall a. NamedThing a => a -> Name
getName Class
clas
ty_args :: [Type]
ty_args = TyCon -> [Type] -> [Type]
filterOutInvisibleTypes (Class -> TyCon
classTyCon Class
clas) [Type]
cls_args
hand_written_bindings :: Bool
hand_written_bindings
= case UserTypeCtxt
ctxt of
InstDeclCtxt stand_alone :: Bool
stand_alone -> Bool -> Bool
not Bool
stand_alone
SpecInstCtxt -> Bool
False
DerivClauseCtxt -> Bool
False
_ -> Bool
True
check_h98_arg_shape :: Bool
check_h98_arg_shape = case UserTypeCtxt
ctxt of
SpecInstCtxt -> Bool
False
DerivClauseCtxt -> Bool
False
SigmaCtxt -> Bool
False
_ -> Bool
True
quantified_constraint :: Bool
quantified_constraint = case UserTypeCtxt
ctxt of
SigmaCtxt -> Bool
True
_ -> Bool
False
head_type_synonym_msg :: SDoc
head_type_synonym_msg = SDoc -> SDoc
parens (
String -> SDoc
text "All instance types must be of the form (T t1 ... tn)" SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "where T is not a synonym." SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "Use TypeSynonymInstances if you want to disable this.")
head_type_args_tyvars_msg :: SDoc
head_type_args_tyvars_msg = SDoc -> SDoc
parens ([SDoc] -> SDoc
vcat [
String -> SDoc
text "All instance types must be of the form (T a1 ... an)",
String -> SDoc
text "where a1 ... an are *distinct type variables*,",
String -> SDoc
text "and each type variable appears at most once in the instance head.",
String -> SDoc
text "Use FlexibleInstances if you want to disable this."])
head_one_type_msg :: SDoc
head_one_type_msg = SDoc -> SDoc
parens (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
String -> SDoc
text "Only one type can be given in an instance head." SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "Use MultiParamTypeClasses if you want to allow more, or zero."
rejected_class_msg :: SDoc
rejected_class_msg = String -> SDoc
text "Class" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
clas_nm)
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "does not support user-specified instances"
tuple_class_msg :: SDoc
tuple_class_msg = String -> SDoc
text "You can't specify an instance for a tuple constraint"
gen_inst_err :: SDoc
gen_inst_err = SDoc
rejected_class_msg SDoc -> SDoc -> SDoc
$$ Int -> SDoc -> SDoc
nest 2 (String -> SDoc
text "(in Safe Haskell)")
abstract_class_msg :: SDoc
abstract_class_msg = String -> SDoc
text "Cannot define instance for abstract class"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
clas_nm)
mb_ty_args_msg :: Maybe SDoc
mb_ty_args_msg
| Bool -> Bool
not (Extension -> DynFlags -> Bool
xopt Extension
LangExt.TypeSynonymInstances DynFlags
dflags)
, Bool -> Bool
not ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
tcInstHeadTyNotSynonym [Type]
ty_args)
= SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just SDoc
head_type_synonym_msg
| Bool -> Bool
not (Extension -> DynFlags -> Bool
xopt Extension
LangExt.FlexibleInstances DynFlags
dflags)
, Bool -> Bool
not ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
tcInstHeadTyAppAllTyVars [Type]
ty_args)
= SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just SDoc
head_type_args_tyvars_msg
| [Type] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
ty_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 1
, Bool -> Bool
not (Extension -> DynFlags -> Bool
xopt Extension
LangExt.MultiParamTypeClasses DynFlags
dflags)
, Bool -> Bool
not (Extension -> DynFlags -> Bool
xopt Extension
LangExt.NullaryTypeClasses DynFlags
dflags Bool -> Bool -> Bool
&& [Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
ty_args)
= SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just SDoc
head_one_type_msg
| Bool
otherwise
= Maybe SDoc
forall a. Maybe a
Nothing
tcInstHeadTyNotSynonym :: Type -> Bool
tcInstHeadTyNotSynonym :: Type -> Bool
tcInstHeadTyNotSynonym ty :: Type
ty
= case Type
ty of
TyConApp tc :: TyCon
tc _ -> Bool -> Bool
not (TyCon -> Bool
isTypeSynonymTyCon TyCon
tc)
_ -> Bool
True
tcInstHeadTyAppAllTyVars :: Type -> Bool
tcInstHeadTyAppAllTyVars :: Type -> Bool
tcInstHeadTyAppAllTyVars ty :: Type
ty
| Just (tc :: TyCon
tc, tys :: [Type]
tys) <- HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe (Type -> Type
dropCasts Type
ty)
= [Type] -> Bool
ok (TyCon -> [Type] -> [Type]
filterOutInvisibleTypes TyCon
tc [Type]
tys)
| LitTy _ <- Type
ty = Bool
True
| Bool
otherwise
= Bool
False
where
ok :: [Type] -> Bool
ok tys :: [Type]
tys = [TyCoVar] -> [Type] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [TyCoVar]
tvs [Type]
tys Bool -> Bool -> Bool
&& [TyCoVar] -> Bool
forall a. Eq a => [a] -> Bool
hasNoDups [TyCoVar]
tvs
where
tvs :: [TyCoVar]
tvs = (Type -> Maybe TyCoVar) -> [Type] -> [TyCoVar]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Type -> Maybe TyCoVar
tcGetTyVar_maybe [Type]
tys
dropCasts :: Type -> Type
dropCasts :: Type -> Type
dropCasts (CastTy ty :: Type
ty _) = Type -> Type
dropCasts Type
ty
dropCasts (AppTy t1 :: Type
t1 t2 :: Type
t2) = Type -> Type -> Type
mkAppTy (Type -> Type
dropCasts Type
t1) (Type -> Type
dropCasts Type
t2)
dropCasts (FunTy t1 :: Type
t1 t2 :: Type
t2) = Type -> Type -> Type
mkFunTy (Type -> Type
dropCasts Type
t1) (Type -> Type
dropCasts Type
t2)
dropCasts (TyConApp tc :: TyCon
tc tys :: [Type]
tys) = TyCon -> [Type] -> Type
mkTyConApp TyCon
tc ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
dropCasts [Type]
tys)
dropCasts (ForAllTy b :: TyVarBinder
b ty :: Type
ty) = TyVarBinder -> Type -> Type
ForAllTy (TyVarBinder -> TyVarBinder
dropCastsB TyVarBinder
b) (Type -> Type
dropCasts Type
ty)
dropCasts ty :: Type
ty = Type
ty
dropCastsB :: TyVarBinder -> TyVarBinder
dropCastsB :: TyVarBinder -> TyVarBinder
dropCastsB b :: TyVarBinder
b = TyVarBinder
b
instTypeErr :: Class -> [Type] -> SDoc -> SDoc
instTypeErr :: Class -> [Type] -> SDoc -> SDoc
instTypeErr cls :: Class
cls tys :: [Type]
tys msg :: SDoc
msg
= SDoc -> Int -> SDoc -> SDoc
hang (SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Illegal instance declaration for")
2 (SDoc -> SDoc
quotes (Class -> [Type] -> SDoc
pprClassPred Class
cls [Type]
tys)))
2 SDoc
msg
checkHasFieldInst :: Class -> [Type] -> TcM ()
checkHasFieldInst :: Class -> [Type] -> TcM ()
checkHasFieldInst cls :: Class
cls tys :: [Type]
tys@[_k_ty :: Type
_k_ty, x_ty :: Type
x_ty, r_ty :: Type
r_ty, _a_ty :: Type
_a_ty] =
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
r_ty of
Nothing -> SDoc -> TcM ()
whoops (String -> SDoc
text "Record data type must be specified")
Just (tc :: TyCon
tc, _)
| TyCon -> Bool
isFamilyTyCon TyCon
tc
-> SDoc -> TcM ()
whoops (String -> SDoc
text "Record data type may not be a data family")
| Bool
otherwise -> case Type -> Maybe FastString
isStrLitTy Type
x_ty of
Just lbl :: FastString
lbl
| Maybe FieldLabel -> Bool
forall a. Maybe a -> Bool
isJust (FastString -> TyCon -> Maybe FieldLabel
lookupTyConFieldLabel FastString
lbl TyCon
tc)
-> SDoc -> TcM ()
whoops (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "already has a field"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (FastString -> SDoc
forall a. Outputable a => a -> SDoc
ppr FastString
lbl))
| Bool
otherwise -> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Nothing
| [FieldLabel] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (TyCon -> [FieldLabel]
tyConFieldLabels TyCon
tc) -> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise -> SDoc -> TcM ()
whoops (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "has fields")
where
whoops :: SDoc -> TcM ()
whoops = SDoc -> TcM ()
addErrTc (SDoc -> TcM ()) -> (SDoc -> SDoc) -> SDoc -> TcM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> [Type] -> SDoc -> SDoc
instTypeErr Class
cls [Type]
tys
checkHasFieldInst _ tys :: [Type]
tys = String -> SDoc -> TcM ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic "checkHasFieldInst" ([Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tys)
validDerivPred :: TyVarSet -> PredType -> Bool
validDerivPred :: VarSet -> Type -> Bool
validDerivPred tv_set :: VarSet
tv_set pred :: Type
pred
= case Type -> PredTree
classifyPredType Type
pred of
ClassPred cls :: Class
cls tys :: [Type]
tys -> Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
typeableClassKey
Bool -> Bool -> Bool
|| Class -> [Type] -> Bool
check_tys Class
cls [Type]
tys
EqPred {} -> Bool
False
_ -> Bool
True
where
check_tys :: Class -> [Type] -> Bool
check_tys cls :: Class
cls tys :: [Type]
tys
= [TyCoVar] -> Bool
forall a. Eq a => [a] -> Bool
hasNoDups [TyCoVar]
fvs
Bool -> Bool -> Bool
&& [TyCoVar] -> Int -> Bool
forall a. [a] -> Int -> Bool
lengthIs [TyCoVar]
fvs (Type -> Int
sizePred Type
pred)
Bool -> Bool -> Bool
&& (TyCoVar -> Bool) -> [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
tv_set) [TyCoVar]
fvs
where tys' :: [Type]
tys' = TyCon -> [Type] -> [Type]
filterOutInvisibleTypes (Class -> TyCon
classTyCon Class
cls) [Type]
tys
fvs :: [TyCoVar]
fvs = [Type] -> [TyCoVar]
fvTypes [Type]
tys'
checkValidInstance :: UserTypeCtxt -> LHsSigType GhcRn -> Type -> TcM ()
checkValidInstance :: UserTypeCtxt -> LHsSigType GhcRn -> Type -> TcM ()
checkValidInstance ctxt :: UserTypeCtxt
ctxt hs_type :: LHsSigType GhcRn
hs_type ty :: Type
ty
| Bool -> Bool
not Bool
is_tc_app
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Instance head is not headed by a class:")
2 ( Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
tau))
| Maybe Class -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Class
mb_cls
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc ([SDoc] -> SDoc
vcat [ String -> SDoc
text "Illegal instance for a" SDoc -> SDoc -> SDoc
<+> TyConFlavour -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> TyConFlavour
tyConFlavour TyCon
tc)
, String -> SDoc
text "A class instance must be for a class" ])
| Bool -> Bool
not Bool
arity_ok
= SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (String -> SDoc
text "Arity mis-match in instance head")
| Bool
otherwise
= do { SrcSpan -> TcM () -> TcM ()
forall a. SrcSpan -> TcRn a -> TcRn a
setSrcSpan SrcSpan
head_loc (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
UserTypeCtxt -> Class -> [Type] -> TcM ()
checkValidInstHead UserTypeCtxt
ctxt Class
clas [Type]
inst_tys
; String -> SDoc -> TcM ()
traceTc "checkValidInstance {" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
; TidyEnv
env0 <- TcM TidyEnv
tcInitTidyEnv
; ExpandMode
expand <- TcM ExpandMode
initialExpandMode
; TidyEnv -> UserTypeCtxt -> ExpandMode -> [Type] -> TcM ()
check_valid_theta TidyEnv
env0 UserTypeCtxt
ctxt ExpandMode
expand [Type]
theta
; Bool
undecidable_ok <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.UndecidableInstances
; if Bool
undecidable_ok
then UserTypeCtxt -> Type -> TcM ()
checkAmbiguity UserTypeCtxt
ctxt Type
ty
else [Type] -> Type -> TcM ()
checkInstTermination [Type]
theta Type
tau
; String -> SDoc -> TcM ()
traceTc "cvi 2" (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
; case (Bool -> Class -> [Type] -> [Type] -> Validity
checkInstCoverage Bool
undecidable_ok Class
clas [Type]
theta [Type]
inst_tys) of
IsValid -> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
NotValid msg :: SDoc
msg -> SDoc -> TcM ()
addErrTc (Class -> [Type] -> SDoc -> SDoc
instTypeErr Class
clas [Type]
inst_tys SDoc
msg)
; String -> SDoc -> TcM ()
traceTc "End checkValidInstance }" SDoc
empty
; () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }
where
(_tvs :: [TyCoVar]
_tvs, theta :: [Type]
theta, tau :: Type
tau) = Type -> ([TyCoVar], [Type], Type)
tcSplitSigmaTy Type
ty
is_tc_app :: Bool
is_tc_app = case Type
tau of { TyConApp {} -> Bool
True; _ -> Bool
False }
TyConApp tc :: TyCon
tc inst_tys :: [Type]
inst_tys = Type
tau
mb_cls :: Maybe Class
mb_cls = TyCon -> Maybe Class
tyConClass_maybe TyCon
tc
Just clas :: Class
clas = Maybe Class
mb_cls
arity_ok :: Bool
arity_ok = [Type]
inst_tys [Type] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthIs` Class -> Int
classArity Class
clas
head_loc :: SrcSpan
head_loc = LHsType GhcRn -> SrcSpan
forall a. HasSrcSpan a => a -> SrcSpan
getLoc (LHsSigType GhcRn -> LHsType GhcRn
forall pass. LHsSigType pass -> LHsType pass
getLHsInstDeclHead LHsSigType GhcRn
hs_type)
checkInstTermination :: ThetaType -> TcPredType -> TcM ()
checkInstTermination :: [Type] -> Type -> TcM ()
checkInstTermination theta :: [Type]
theta head_pred :: Type
head_pred
= VarSet -> [Type] -> TcM ()
check_preds VarSet
emptyVarSet [Type]
theta
where
head_fvs :: [TyCoVar]
head_fvs = Type -> [TyCoVar]
fvType Type
head_pred
head_size :: Int
head_size = Type -> Int
sizeType Type
head_pred
check_preds :: VarSet -> [PredType] -> TcM ()
check_preds :: VarSet -> [Type] -> TcM ()
check_preds foralld_tvs :: VarSet
foralld_tvs preds :: [Type]
preds = (Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (VarSet -> Type -> TcM ()
check VarSet
foralld_tvs) [Type]
preds
check :: VarSet -> PredType -> TcM ()
check :: VarSet -> Type -> TcM ()
check foralld_tvs :: VarSet
foralld_tvs pred :: Type
pred
= case Type -> PredTree
classifyPredType Type
pred of
EqPred {} -> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
IrredPred {} -> VarSet -> Type -> Int -> TcM ()
check2 VarSet
foralld_tvs Type
pred (Type -> Int
sizeType Type
pred)
ClassPred cls :: Class
cls tys :: [Type]
tys
| Class -> Bool
isTerminatingClass Class
cls
-> () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Class -> Bool
isCTupleClass Class
cls
-> VarSet -> [Type] -> TcM ()
check_preds VarSet
foralld_tvs [Type]
tys
| Bool
otherwise
-> VarSet -> Type -> Int -> TcM ()
check2 VarSet
foralld_tvs Type
pred Int
bogus_size
where
bogus_size :: Int
bogus_size = 1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Type] -> Int
sizeTypes (TyCon -> [Type] -> [Type]
filterOutInvisibleTypes (Class -> TyCon
classTyCon Class
cls) [Type]
tys)
ForAllPred tvs :: [TyVarBinder]
tvs _ head_pred' :: Type
head_pred'
-> VarSet -> Type -> TcM ()
check (VarSet
foralld_tvs VarSet -> [TyCoVar] -> VarSet
`extendVarSetList` [TyVarBinder] -> [TyCoVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyVarBinder]
tvs) Type
head_pred'
check2 :: VarSet -> Type -> Int -> TcM ()
check2 foralld_tvs :: VarSet
foralld_tvs pred :: Type
pred pred_size :: Int
pred_size
| Bool -> Bool
not ([TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
bad_tvs) = SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc ([TyCoVar] -> SDoc -> SDoc -> SDoc
noMoreMsg [TyCoVar]
bad_tvs SDoc
what (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
head_pred))
| Bool -> Bool
not (Type -> Bool
isTyFamFree Type
pred) = SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (SDoc -> SDoc
nestedMsg SDoc
what)
| Int
pred_size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
head_size = SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (SDoc -> SDoc -> SDoc
smallerMsg SDoc
what (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
head_pred))
| Bool
otherwise = () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
what :: SDoc
what = String -> SDoc
text "constraint" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred)
bad_tvs :: [TyCoVar]
bad_tvs = (TyCoVar -> Bool) -> [TyCoVar] -> [TyCoVar]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
foralld_tvs) (Type -> [TyCoVar]
fvType Type
pred)
[TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. Eq a => [a] -> [a] -> [a]
\\ [TyCoVar]
head_fvs
smallerMsg :: SDoc -> SDoc -> SDoc
smallerMsg :: SDoc -> SDoc -> SDoc
smallerMsg what :: SDoc
what inst_head :: SDoc
inst_head
= [SDoc] -> SDoc
vcat [ SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "The" SDoc -> SDoc -> SDoc
<+> SDoc
what)
2 ([SDoc] -> SDoc
sep [ String -> SDoc
text "is no smaller than"
, String -> SDoc
text "the instance head" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes SDoc
inst_head ])
, SDoc -> SDoc
parens SDoc
undecidableMsg ]
noMoreMsg :: [TcTyVar] -> SDoc -> SDoc -> SDoc
noMoreMsg :: [TyCoVar] -> SDoc -> SDoc -> SDoc
noMoreMsg tvs :: [TyCoVar]
tvs what :: SDoc
what inst_head :: SDoc
inst_head
= [SDoc] -> SDoc
vcat [ SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Variable" SDoc -> SDoc -> SDoc
<> [TyCoVar] -> SDoc
forall a. [a] -> SDoc
plural [TyCoVar]
tvs1 SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes ((TyCoVar -> SDoc) -> [TyCoVar] -> SDoc
forall a. (a -> SDoc) -> [a] -> SDoc
pprWithCommas TyCoVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
tvs1)
SDoc -> SDoc -> SDoc
<+> SDoc
occurs SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "more often")
2 ([SDoc] -> SDoc
sep [ String -> SDoc
text "in the" SDoc -> SDoc -> SDoc
<+> SDoc
what
, String -> SDoc
text "than in the instance head" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes SDoc
inst_head ])
, SDoc -> SDoc
parens SDoc
undecidableMsg ]
where
tvs1 :: [TyCoVar]
tvs1 = [TyCoVar] -> [TyCoVar]
forall a. Eq a => [a] -> [a]
nub [TyCoVar]
tvs
occurs :: SDoc
occurs = if [TyCoVar] -> Bool
forall a. [a] -> Bool
isSingleton [TyCoVar]
tvs1 then String -> SDoc
text "occurs"
else String -> SDoc
text "occur"
undecidableMsg, constraintKindsMsg :: SDoc
undecidableMsg :: SDoc
undecidableMsg = String -> SDoc
text "Use UndecidableInstances to permit this"
constraintKindsMsg :: SDoc
constraintKindsMsg = String -> SDoc
text "Use ConstraintKinds to permit this"
checkValidCoAxiom :: CoAxiom Branched -> TcM ()
checkValidCoAxiom :: CoAxiom Branched -> TcM ()
checkValidCoAxiom ax :: CoAxiom Branched
ax@(CoAxiom { co_ax_tc :: forall (br :: BranchFlag). CoAxiom br -> TyCon
co_ax_tc = TyCon
fam_tc, co_ax_branches :: forall (br :: BranchFlag). CoAxiom br -> Branches br
co_ax_branches = Branches Branched
branches })
= do { (CoAxBranch -> TcM ()) -> [CoAxBranch] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (TyCon -> CoAxBranch -> TcM ()
checkValidCoAxBranch TyCon
fam_tc) [CoAxBranch]
branch_list
; ([CoAxBranch]
-> CoAxBranch -> IOEnv (Env TcGblEnv TcLclEnv) [CoAxBranch])
-> [CoAxBranch] -> [CoAxBranch] -> TcM ()
forall (m :: * -> *) a b.
Monad m =>
(a -> b -> m a) -> a -> [b] -> m ()
foldlM_ [CoAxBranch]
-> CoAxBranch -> IOEnv (Env TcGblEnv TcLclEnv) [CoAxBranch]
check_branch_compat [] [CoAxBranch]
branch_list }
where
branch_list :: [CoAxBranch]
branch_list = Branches Branched -> [CoAxBranch]
forall (br :: BranchFlag). Branches br -> [CoAxBranch]
fromBranches Branches Branched
branches
injectivity :: Injectivity
injectivity = TyCon -> Injectivity
tyConInjectivityInfo TyCon
fam_tc
check_branch_compat :: [CoAxBranch]
-> CoAxBranch
-> TcM [CoAxBranch]
check_branch_compat :: [CoAxBranch]
-> CoAxBranch -> IOEnv (Env TcGblEnv TcLclEnv) [CoAxBranch]
check_branch_compat prev_branches :: [CoAxBranch]
prev_branches cur_branch :: CoAxBranch
cur_branch
| CoAxBranch
cur_branch CoAxBranch -> [CoAxBranch] -> Bool
`isDominatedBy` [CoAxBranch]
prev_branches
= do { WarnReason -> SrcSpan -> SDoc -> TcM ()
addWarnAt WarnReason
NoReason (CoAxBranch -> SrcSpan
coAxBranchSpan CoAxBranch
cur_branch) (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$
TyCon -> CoAxBranch -> SDoc
inaccessibleCoAxBranch TyCon
fam_tc CoAxBranch
cur_branch
; [CoAxBranch] -> IOEnv (Env TcGblEnv TcLclEnv) [CoAxBranch]
forall (m :: * -> *) a. Monad m => a -> m a
return [CoAxBranch]
prev_branches }
| Bool
otherwise
= do { [CoAxBranch] -> CoAxBranch -> TcM ()
check_injectivity [CoAxBranch]
prev_branches CoAxBranch
cur_branch
; [CoAxBranch] -> IOEnv (Env TcGblEnv TcLclEnv) [CoAxBranch]
forall (m :: * -> *) a. Monad m => a -> m a
return (CoAxBranch
cur_branch CoAxBranch -> [CoAxBranch] -> [CoAxBranch]
forall a. a -> [a] -> [a]
: [CoAxBranch]
prev_branches) }
check_injectivity :: [CoAxBranch] -> CoAxBranch -> TcM ()
check_injectivity prev_branches :: [CoAxBranch]
prev_branches cur_branch :: CoAxBranch
cur_branch
| Injective inj :: [Bool]
inj <- Injectivity
injectivity
= do { let conflicts :: [CoAxBranch]
conflicts =
([CoAxBranch], Int) -> [CoAxBranch]
forall a b. (a, b) -> a
fst (([CoAxBranch], Int) -> [CoAxBranch])
-> ([CoAxBranch], Int) -> [CoAxBranch]
forall a b. (a -> b) -> a -> b
$ (([CoAxBranch], Int) -> CoAxBranch -> ([CoAxBranch], Int))
-> ([CoAxBranch], Int) -> [CoAxBranch] -> ([CoAxBranch], Int)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ([Bool]
-> [CoAxBranch]
-> CoAxBranch
-> ([CoAxBranch], Int)
-> CoAxBranch
-> ([CoAxBranch], Int)
gather_conflicts [Bool]
inj [CoAxBranch]
prev_branches CoAxBranch
cur_branch)
([], 0) [CoAxBranch]
prev_branches
; ((SDoc, SrcSpan) -> TcM ()) -> [(SDoc, SrcSpan)] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(err :: SDoc
err, span :: SrcSpan
span) -> SrcSpan -> TcM () -> TcM ()
forall a. SrcSpan -> TcRn a -> TcRn a
setSrcSpan SrcSpan
span (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$ SDoc -> TcM ()
addErr SDoc
err)
(CoAxiom Branched
-> CoAxBranch -> [Bool] -> [CoAxBranch] -> [(SDoc, SrcSpan)]
forall (br :: BranchFlag).
CoAxiom br
-> CoAxBranch -> [Bool] -> [CoAxBranch] -> [(SDoc, SrcSpan)]
makeInjectivityErrors CoAxiom Branched
ax CoAxBranch
cur_branch [Bool]
inj [CoAxBranch]
conflicts) }
| Bool
otherwise
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
gather_conflicts :: [Bool]
-> [CoAxBranch]
-> CoAxBranch
-> ([CoAxBranch], Int)
-> CoAxBranch
-> ([CoAxBranch], Int)
gather_conflicts inj :: [Bool]
inj prev_branches :: [CoAxBranch]
prev_branches cur_branch :: CoAxBranch
cur_branch (acc :: [CoAxBranch]
acc, n :: Int
n) branch :: CoAxBranch
branch
= case [Bool] -> CoAxBranch -> CoAxBranch -> InjectivityCheckResult
injectiveBranches [Bool]
inj CoAxBranch
cur_branch CoAxBranch
branch of
InjectivityUnified ax1 :: CoAxBranch
ax1 ax2 :: CoAxBranch
ax2
| CoAxBranch
ax1 CoAxBranch -> [CoAxBranch] -> Bool
`isDominatedBy` ([CoAxBranch] -> Int -> CoAxBranch -> [CoAxBranch]
replace_br [CoAxBranch]
prev_branches Int
n CoAxBranch
ax2)
-> ([CoAxBranch]
acc, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
| Bool
otherwise
-> (CoAxBranch
branch CoAxBranch -> [CoAxBranch] -> [CoAxBranch]
forall a. a -> [a] -> [a]
: [CoAxBranch]
acc, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
InjectivityAccepted -> ([CoAxBranch]
acc, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
replace_br :: [CoAxBranch] -> Int -> CoAxBranch -> [CoAxBranch]
replace_br :: [CoAxBranch] -> Int -> CoAxBranch -> [CoAxBranch]
replace_br brs :: [CoAxBranch]
brs n :: Int
n br :: CoAxBranch
br = Int -> [CoAxBranch] -> [CoAxBranch]
forall a. Int -> [a] -> [a]
take Int
n [CoAxBranch]
brs [CoAxBranch] -> [CoAxBranch] -> [CoAxBranch]
forall a. [a] -> [a] -> [a]
++ [CoAxBranch
br] [CoAxBranch] -> [CoAxBranch] -> [CoAxBranch]
forall a. [a] -> [a] -> [a]
++ Int -> [CoAxBranch] -> [CoAxBranch]
forall a. Int -> [a] -> [a]
drop (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) [CoAxBranch]
brs
checkValidCoAxBranch :: TyCon -> CoAxBranch -> TcM ()
checkValidCoAxBranch :: TyCon -> CoAxBranch -> TcM ()
checkValidCoAxBranch fam_tc :: TyCon
fam_tc
(CoAxBranch { cab_tvs :: CoAxBranch -> [TyCoVar]
cab_tvs = [TyCoVar]
tvs, cab_cvs :: CoAxBranch -> [TyCoVar]
cab_cvs = [TyCoVar]
cvs
, cab_lhs :: CoAxBranch -> [Type]
cab_lhs = [Type]
typats
, cab_rhs :: CoAxBranch -> Type
cab_rhs = Type
rhs, cab_loc :: CoAxBranch -> SrcSpan
cab_loc = SrcSpan
loc })
= SrcSpan -> TcM () -> TcM ()
forall a. SrcSpan -> TcRn a -> TcRn a
setSrcSpan SrcSpan
loc (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
TyCon -> [TyCoVar] -> [Type] -> Type -> TcM ()
checkValidTyFamEqn TyCon
fam_tc ([TyCoVar]
tvs[TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. [a] -> [a] -> [a]
++[TyCoVar]
cvs) [Type]
typats Type
rhs
checkValidTyFamEqn :: TyCon
-> [Var]
-> [Type]
-> Type
-> TcM ()
checkValidTyFamEqn :: TyCon -> [TyCoVar] -> [Type] -> Type -> TcM ()
checkValidTyFamEqn fam_tc :: TyCon
fam_tc qvs :: [TyCoVar]
qvs typats :: [Type]
typats rhs :: Type
rhs
= do { TyCon -> [TyCoVar] -> [Type] -> Type -> TcM ()
checkValidFamPats TyCon
fam_tc [TyCoVar]
qvs [Type]
typats Type
rhs
; Type -> TcM ()
checkValidMonoType Type
rhs
; Bool
undecidable_ok <- Extension -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. Extension -> TcRnIf gbl lcl Bool
xoptM Extension
LangExt.UndecidableInstances
; String -> SDoc -> TcM ()
traceTc "checkVTFE" (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
fam_tc SDoc -> SDoc -> SDoc
$$ Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
rhs SDoc -> SDoc -> SDoc
$$ [(TyCon, [Type])] -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Type -> [(TyCon, [Type])]
tcTyFamInsts Type
rhs))
; Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
undecidable_ok (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
(SDoc -> TcM ()) -> [SDoc] -> TcM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ SDoc -> TcM ()
addErrTc (TyCon -> [Type] -> [(TyCon, [Type])] -> [SDoc]
checkFamInstRhs TyCon
fam_tc [Type]
typats (Type -> [(TyCon, [Type])]
tcTyFamInsts Type
rhs)) }
checkFamInstRhs :: TyCon -> [Type]
-> [(TyCon, [Type])]
-> [MsgDoc]
checkFamInstRhs :: TyCon -> [Type] -> [(TyCon, [Type])] -> [SDoc]
checkFamInstRhs lhs_tc :: TyCon
lhs_tc lhs_tys :: [Type]
lhs_tys famInsts :: [(TyCon, [Type])]
famInsts
= ((TyCon, [Type]) -> Maybe SDoc) -> [(TyCon, [Type])] -> [SDoc]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (TyCon, [Type]) -> Maybe SDoc
check [(TyCon, [Type])]
famInsts
where
lhs_size :: Int
lhs_size = TyCon -> [Type] -> Int
sizeTyConAppArgs TyCon
lhs_tc [Type]
lhs_tys
inst_head :: SDoc
inst_head = Type -> SDoc
pprType (TyCon -> [Type] -> Type
TyConApp TyCon
lhs_tc [Type]
lhs_tys)
lhs_fvs :: [TyCoVar]
lhs_fvs = [Type] -> [TyCoVar]
fvTypes [Type]
lhs_tys
check :: (TyCon, [Type]) -> Maybe SDoc
check (tc :: TyCon
tc, tys :: [Type]
tys)
| Bool -> Bool
not ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
isTyFamFree [Type]
tys) = SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just (SDoc -> SDoc
nestedMsg SDoc
what)
| Bool -> Bool
not ([TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
bad_tvs) = SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just ([TyCoVar] -> SDoc -> SDoc -> SDoc
noMoreMsg [TyCoVar]
bad_tvs SDoc
what SDoc
inst_head)
| Int
lhs_size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
fam_app_size = SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just (SDoc -> SDoc -> SDoc
smallerMsg SDoc
what SDoc
inst_head)
| Bool
otherwise = Maybe SDoc
forall a. Maybe a
Nothing
where
what :: SDoc
what = String -> SDoc
text "type family application"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Type -> SDoc
pprType (TyCon -> [Type] -> Type
TyConApp TyCon
tc [Type]
tys))
fam_app_size :: Int
fam_app_size = TyCon -> [Type] -> Int
sizeTyConAppArgs TyCon
tc [Type]
tys
bad_tvs :: [TyCoVar]
bad_tvs = [Type] -> [TyCoVar]
fvTypes [Type]
tys [TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. Eq a => [a] -> [a] -> [a]
\\ [TyCoVar]
lhs_fvs
checkValidFamPats :: TyCon -> [Var]
-> [Type]
-> Type
-> TcM ()
checkValidFamPats :: TyCon -> [TyCoVar] -> [Type] -> Type -> TcM ()
checkValidFamPats fam_tc :: TyCon
fam_tc qvs :: [TyCoVar]
qvs pats :: [Type]
pats rhs :: Type
rhs
= do { TyCon -> [Type] -> TcM ()
checkValidTypePats TyCon
fam_tc [Type]
pats
; TyCon -> [TyCoVar] -> [Type] -> Type -> TcM ()
checkFamPatBinders TyCon
fam_tc [TyCoVar]
qvs [Type]
pats Type
rhs
; String -> SDoc -> TcM ()
traceTc "checkValidFamPats" (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
fam_tc SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
pats)
}
checkFamPatBinders :: TyCon
-> [TcTyVar]
-> [TcType]
-> Type
-> TcM ()
checkFamPatBinders :: TyCon -> [TyCoVar] -> [Type] -> Type -> TcM ()
checkFamPatBinders fam_tc :: TyCon
fam_tc qtvs :: [TyCoVar]
qtvs pats :: [Type]
pats rhs :: Type
rhs
= do { String -> SDoc -> TcM ()
traceTc "checkFamPatBinders" (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ Type -> SDoc
debugPprType (TyCon -> [Type] -> Type
mkTyConApp TyCon
fam_tc [Type]
pats)
, Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> [Type] -> Type
mkTyConApp TyCon
fam_tc [Type]
pats)
, String -> SDoc
text "qtvs:" SDoc -> SDoc -> SDoc
<+> [TyCoVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
qtvs
, String -> SDoc
text "rhs_tvs:" SDoc -> SDoc -> SDoc
<+> VarSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr (FV -> VarSet
fvVarSet FV
rhs_fvs)
, String -> SDoc
text "pat_tvs:" SDoc -> SDoc -> SDoc
<+> VarSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr VarSet
pat_tvs
, String -> SDoc
text "exact_pat_tvs:" SDoc -> SDoc -> SDoc
<+> VarSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr VarSet
exact_pat_tvs ]
; [TyCoVar] -> SDoc -> SDoc -> TcM ()
check_tvs [TyCoVar]
bad_rhs_tvs (String -> SDoc
text "mentioned in the RHS")
(String -> SDoc
text "bound on the LHS of")
; [TyCoVar] -> SDoc -> SDoc -> TcM ()
check_tvs [TyCoVar]
bad_qtvs (String -> SDoc
text "bound by a forall")
(String -> SDoc
text "used in")
; Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (TyCon -> Bool
isTypeFamilyTyCon TyCon
fam_tc) (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$
case Int -> [Type] -> [Type]
forall a. Int -> [a] -> [a]
drop (TyCon -> Int
tyConArity TyCon
fam_tc) [Type]
pats of
[] -> () -> TcM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
spec_arg :: Type
spec_arg:_ ->
SDoc -> TcM ()
addErr (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text "Illegal oversaturated visible kind argument:"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Char -> SDoc
char '@' SDoc -> SDoc -> SDoc
<> Type -> SDoc
pprParendType Type
spec_arg) }
where
pat_tvs :: VarSet
pat_tvs = [Type] -> VarSet
tyCoVarsOfTypes [Type]
pats
exact_pat_tvs :: VarSet
exact_pat_tvs = [Type] -> VarSet
exactTyCoVarsOfTypes [Type]
pats
rhs_fvs :: FV
rhs_fvs = Type -> FV
tyCoFVsOfType Type
rhs
used_tvs :: VarSet
used_tvs = VarSet
pat_tvs VarSet -> VarSet -> VarSet
`unionVarSet` FV -> VarSet
fvVarSet FV
rhs_fvs
bad_qtvs :: [TyCoVar]
bad_qtvs = (TyCoVar -> Bool) -> [TyCoVar] -> [TyCoVar]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
used_tvs) [TyCoVar]
qtvs
bad_rhs_tvs :: [TyCoVar]
bad_rhs_tvs = (TyCoVar -> Bool) -> [TyCoVar] -> [TyCoVar]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
exact_pat_tvs) (FV -> [TyCoVar]
fvVarList FV
rhs_fvs)
dodgy_tvs :: VarSet
dodgy_tvs = VarSet
pat_tvs VarSet -> VarSet -> VarSet
`minusVarSet` VarSet
exact_pat_tvs
check_tvs :: [TyCoVar] -> SDoc -> SDoc -> TcM ()
check_tvs tvs :: [TyCoVar]
tvs what :: SDoc
what what2 :: SDoc
what2
= Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
tvs) (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$ SrcSpan -> SDoc -> TcM ()
addErrAt (TyCoVar -> SrcSpan
forall a. NamedThing a => a -> SrcSpan
getSrcSpan ([TyCoVar] -> TyCoVar
forall a. [a] -> a
head [TyCoVar]
tvs)) (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Type variable" SDoc -> SDoc -> SDoc
<> [TyCoVar] -> SDoc
forall a. [a] -> SDoc
plural [TyCoVar]
tvs SDoc -> SDoc -> SDoc
<+> [TyCoVar] -> SDoc
forall a. Outputable a => [a] -> SDoc
pprQuotedList [TyCoVar]
tvs
SDoc -> SDoc -> SDoc
<+> [TyCoVar] -> SDoc
forall a. [a] -> SDoc
isOrAre [TyCoVar]
tvs SDoc -> SDoc -> SDoc
<+> SDoc
what SDoc -> SDoc -> SDoc
<> SDoc
comma)
2 ([SDoc] -> SDoc
vcat [ String -> SDoc
text "but not" SDoc -> SDoc -> SDoc
<+> SDoc
what2 SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "the family instance"
, [TyCoVar] -> SDoc
forall (t :: * -> *). Foldable t => t TyCoVar -> SDoc
mk_extra [TyCoVar]
tvs ])
mk_extra :: t TyCoVar -> SDoc
mk_extra tvs :: t TyCoVar
tvs = Bool -> SDoc -> SDoc
ppWhen ((TyCoVar -> Bool) -> t TyCoVar -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
dodgy_tvs) t TyCoVar
tvs) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "The real LHS (expanding synonyms) is:")
2 (TyCon -> [Type] -> SDoc
pprTypeApp TyCon
fam_tc ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
expandTypeSynonyms [Type]
pats))
checkValidTypePats :: TyCon -> [Type] -> TcM ()
checkValidTypePats :: TyCon -> [Type] -> TcM ()
checkValidTypePats tc :: TyCon
tc pat_ty_args :: [Type]
pat_ty_args = do
(Type -> TcM ()) -> [Type] -> TcM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Type -> TcM ()
checkValidMonoType [Type]
pat_ty_args
case TyCon -> [Type] -> [(Bool, TyCon, [Type])]
tcTyConAppTyFamInstsAndVis TyCon
tc [Type]
pat_ty_args of
[] -> () -> TcM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
((tf_is_invis_arg :: Bool
tf_is_invis_arg, tf_tc :: TyCon
tf_tc, tf_args :: [Type]
tf_args):_) -> SDoc -> TcM ()
forall a. SDoc -> TcM a
failWithTc (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$
Bool -> Type -> SDoc
ty_fam_inst_illegal_err Bool
tf_is_invis_arg (TyCon -> [Type] -> Type
mkTyConApp TyCon
tf_tc [Type]
tf_args)
where
inst_ty :: Type
inst_ty = TyCon -> [Type] -> Type
mkTyConApp TyCon
tc [Type]
pat_ty_args
ty_fam_inst_illegal_err :: Bool -> Type -> SDoc
ty_fam_inst_illegal_err :: Bool -> Type -> SDoc
ty_fam_inst_illegal_err invis_arg :: Bool
invis_arg ty :: Type
ty
= Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen Bool
invis_arg (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Illegal type synonym family application"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty) SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "in instance" SDoc -> SDoc -> SDoc
<> SDoc
colon)
2 (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
inst_ty)
inaccessibleCoAxBranch :: TyCon -> CoAxBranch -> SDoc
inaccessibleCoAxBranch :: TyCon -> CoAxBranch -> SDoc
inaccessibleCoAxBranch fam_tc :: TyCon
fam_tc cur_branch :: CoAxBranch
cur_branch
= String -> SDoc
text "Type family instance equation is overlapped:" SDoc -> SDoc -> SDoc
$$
Int -> SDoc -> SDoc
nest 2 (TyCon -> CoAxBranch -> SDoc
pprCoAxBranchUser TyCon
fam_tc CoAxBranch
cur_branch)
nestedMsg :: SDoc -> SDoc
nestedMsg :: SDoc -> SDoc
nestedMsg what :: SDoc
what
= [SDoc] -> SDoc
sep [ String -> SDoc
text "Illegal nested" SDoc -> SDoc -> SDoc
<+> SDoc
what
, SDoc -> SDoc
parens SDoc
undecidableMsg ]
badATErr :: Name -> Name -> SDoc
badATErr :: Name -> Name -> SDoc
badATErr clas :: Name
clas op :: Name
op
= [SDoc] -> SDoc
hsep [String -> SDoc
text "Class", SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
clas),
String -> SDoc
text "does not have an associated type", SDoc -> SDoc
quotes (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
op)]
checkConsistentFamInst :: AssocInstInfo
-> TyCon
-> CoAxBranch
-> TcM ()
checkConsistentFamInst :: AssocInstInfo -> TyCon -> CoAxBranch -> TcM ()
checkConsistentFamInst NotAssociated _ _
= () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkConsistentFamInst (InClsInst { ai_class :: AssocInstInfo -> Class
ai_class = Class
clas
, ai_tyvars :: AssocInstInfo -> [TyCoVar]
ai_tyvars = [TyCoVar]
inst_tvs
, ai_inst_env :: AssocInstInfo -> VarEnv Type
ai_inst_env = VarEnv Type
mini_env })
fam_tc :: TyCon
fam_tc branch :: CoAxBranch
branch
= do { String -> SDoc -> TcM ()
traceTc "checkConsistentFamInst" ([SDoc] -> SDoc
vcat [ [TyCoVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
inst_tvs
, [(Type, Type, ArgFlag)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Type, Type, ArgFlag)]
arg_triples
, VarEnv Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr VarEnv Type
mini_env
, [TyCoVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyCoVar]
ax_tvs
, [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
ax_arg_tys
, [(Type, Type, ArgFlag)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Type, Type, ArgFlag)]
arg_triples ])
; Bool -> SDoc -> TcM ()
checkTc (TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just (Class -> TyCon
classTyCon Class
clas) Maybe TyCon -> Maybe TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Maybe TyCon
tyConAssoc_maybe TyCon
fam_tc)
(Name -> Name -> SDoc
badATErr (Class -> Name
className Class
clas) (TyCon -> Name
tyConName TyCon
fam_tc))
; [(Type, Type, ArgFlag)] -> TcM ()
check_match [(Type, Type, ArgFlag)]
arg_triples
}
where
(ax_tvs :: [TyCoVar]
ax_tvs, ax_arg_tys :: [Type]
ax_arg_tys, _) = CoAxBranch -> ([TyCoVar], [Type], Type)
etaExpandCoAxBranch CoAxBranch
branch
arg_triples :: [(Type,Type, ArgFlag)]
arg_triples :: [(Type, Type, ArgFlag)]
arg_triples = [ (Type
cls_arg_ty, Type
at_arg_ty, ArgFlag
vis)
| (fam_tc_tv :: TyCoVar
fam_tc_tv, vis :: ArgFlag
vis, at_arg_ty :: Type
at_arg_ty)
<- [TyCoVar] -> [ArgFlag] -> [Type] -> [(TyCoVar, ArgFlag, Type)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 (TyCon -> [TyCoVar]
tyConTyVars TyCon
fam_tc)
(TyCon -> [Type] -> [ArgFlag]
tyConArgFlags TyCon
fam_tc [Type]
ax_arg_tys)
[Type]
ax_arg_tys
, Just cls_arg_ty :: Type
cls_arg_ty <- [VarEnv Type -> TyCoVar -> Maybe Type
forall a. VarEnv a -> TyCoVar -> Maybe a
lookupVarEnv VarEnv Type
mini_env TyCoVar
fam_tc_tv] ]
pp_wrong_at_arg :: ArgFlag -> SDoc
pp_wrong_at_arg vis :: ArgFlag
vis
= Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen (ArgFlag -> Bool
isInvisibleArgFlag ArgFlag
vis) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ String -> SDoc
text "Type indexes must match class instance head"
, String -> SDoc
text "Expected:" SDoc -> SDoc -> SDoc
<+> SDoc
pp_expected_ty
, String -> SDoc
text " Actual:" SDoc -> SDoc -> SDoc
<+> SDoc
pp_actual_ty ]
(tidy_env1 :: TidyEnv
tidy_env1, _) = TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
tidyVarBndrs TidyEnv
emptyTidyEnv [TyCoVar]
inst_tvs
(tidy_env2 :: TidyEnv
tidy_env2, _) = TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
tidyCoAxBndrsForUser TidyEnv
tidy_env1 ([TyCoVar]
ax_tvs [TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. Eq a => [a] -> [a] -> [a]
\\ [TyCoVar]
inst_tvs)
pp_expected_ty :: SDoc
pp_expected_ty = PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprIfaceTypeApp PprPrec
topPrec (TyCon -> IfaceTyCon
toIfaceTyCon TyCon
fam_tc) (IfaceAppArgs -> SDoc) -> IfaceAppArgs -> SDoc
forall a b. (a -> b) -> a -> b
$
TyCon -> [Type] -> IfaceAppArgs
toIfaceTcArgs TyCon
fam_tc ([Type] -> IfaceAppArgs) -> [Type] -> IfaceAppArgs
forall a b. (a -> b) -> a -> b
$
[ case VarEnv Type -> TyCoVar -> Maybe Type
forall a. VarEnv a -> TyCoVar -> Maybe a
lookupVarEnv VarEnv Type
mini_env TyCoVar
at_tv of
Just cls_arg_ty :: Type
cls_arg_ty -> TidyEnv -> Type -> Type
tidyType TidyEnv
tidy_env2 Type
cls_arg_ty
Nothing -> TyCoVar -> Type
mk_wildcard TyCoVar
at_tv
| TyCoVar
at_tv <- TyCon -> [TyCoVar]
tyConTyVars TyCon
fam_tc ]
pp_actual_ty :: SDoc
pp_actual_ty = PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
pprIfaceTypeApp PprPrec
topPrec (TyCon -> IfaceTyCon
toIfaceTyCon TyCon
fam_tc) (IfaceAppArgs -> SDoc) -> IfaceAppArgs -> SDoc
forall a b. (a -> b) -> a -> b
$
TyCon -> [Type] -> IfaceAppArgs
toIfaceTcArgs TyCon
fam_tc ([Type] -> IfaceAppArgs) -> [Type] -> IfaceAppArgs
forall a b. (a -> b) -> a -> b
$
TidyEnv -> [Type] -> [Type]
tidyTypes TidyEnv
tidy_env2 [Type]
ax_arg_tys
mk_wildcard :: TyCoVar -> Type
mk_wildcard at_tv :: TyCoVar
at_tv = TyCoVar -> Type
mkTyVarTy (Name -> Type -> TyCoVar
mkTyVar Name
tv_name (TyCoVar -> Type
tyVarKind TyCoVar
at_tv))
tv_name :: Name
tv_name = Unique -> OccName -> SrcSpan -> Name
mkInternalName (Int -> Unique
mkAlphaTyVarUnique 1) (String -> OccName
mkTyVarOcc "_") SrcSpan
noSrcSpan
check_match :: [(Type,Type,ArgFlag)] -> TcM ()
check_match :: [(Type, Type, ArgFlag)] -> TcM ()
check_match triples :: [(Type, Type, ArgFlag)]
triples = TCvSubst -> TCvSubst -> [(Type, Type, ArgFlag)] -> TcM ()
go TCvSubst
emptyTCvSubst TCvSubst
emptyTCvSubst [(Type, Type, ArgFlag)]
triples
go :: TCvSubst -> TCvSubst -> [(Type, Type, ArgFlag)] -> TcM ()
go _ _ [] = () -> TcM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
go lr_subst :: TCvSubst
lr_subst rl_subst :: TCvSubst
rl_subst ((ty1 :: Type
ty1,ty2 :: Type
ty2,vis :: ArgFlag
vis):triples :: [(Type, Type, ArgFlag)]
triples)
| Just lr_subst1 :: TCvSubst
lr_subst1 <- (TyCoVar -> BindFlag) -> TCvSubst -> Type -> Type -> Maybe TCvSubst
tcMatchTyX_BM TyCoVar -> BindFlag
bind_me TCvSubst
lr_subst Type
ty1 Type
ty2
, Just rl_subst1 :: TCvSubst
rl_subst1 <- (TyCoVar -> BindFlag) -> TCvSubst -> Type -> Type -> Maybe TCvSubst
tcMatchTyX_BM TyCoVar -> BindFlag
bind_me TCvSubst
rl_subst Type
ty2 Type
ty1
= TCvSubst -> TCvSubst -> [(Type, Type, ArgFlag)] -> TcM ()
go TCvSubst
lr_subst1 TCvSubst
rl_subst1 [(Type, Type, ArgFlag)]
triples
| Bool
otherwise
= SDoc -> TcM ()
addErrTc (ArgFlag -> SDoc
pp_wrong_at_arg ArgFlag
vis)
no_bind_set :: VarSet
no_bind_set = [TyCoVar] -> VarSet
mkVarSet [TyCoVar]
inst_tvs
bind_me :: TyCoVar -> BindFlag
bind_me tv :: TyCoVar
tv | TyCoVar
tv TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
no_bind_set = BindFlag
Skolem
| Bool
otherwise = BindFlag
BindMe
checkValidTelescope :: TyCon -> TcM ()
checkValidTelescope :: TyCon -> TcM ()
checkValidTelescope tc :: TyCon
tc
= Bool -> TcM () -> TcM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([VarBndr TyCoVar TyConBndrVis] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [VarBndr TyCoVar TyConBndrVis]
bad_tcbs) (TcM () -> TcM ()) -> TcM () -> TcM ()
forall a b. (a -> b) -> a -> b
$ SDoc -> TcM ()
addErr (SDoc -> TcM ()) -> SDoc -> TcM ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "The kind of" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc) SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "is ill-scoped")
2 (String -> SDoc
text "Inferred kind:" SDoc -> SDoc -> SDoc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> Type -> SDoc
ppr_untidy (TyCon -> Type
tyConKind TyCon
tc))
, SDoc
extra
, SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Perhaps try this order instead:")
2 ([TyCoVar] -> SDoc
pprTyVars [TyCoVar]
sorted_tidied_tvs) ]
where
ppr_untidy :: Type -> SDoc
ppr_untidy ty :: Type
ty = IfaceType -> SDoc
pprIfaceType (Type -> IfaceType
toIfaceType Type
ty)
tcbs :: [VarBndr TyCoVar TyConBndrVis]
tcbs = TyCon -> [VarBndr TyCoVar TyConBndrVis]
tyConBinders TyCon
tc
tvs :: [TyCoVar]
tvs = [VarBndr TyCoVar TyConBndrVis] -> [TyCoVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [VarBndr TyCoVar TyConBndrVis]
tcbs
(_, sorted_tidied_tvs :: [TyCoVar]
sorted_tidied_tvs) = TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])
tidyVarBndrs TidyEnv
emptyTidyEnv ([TyCoVar] -> [TyCoVar]
scopedSort [TyCoVar]
tvs)
(_, bad_tcbs :: [VarBndr TyCoVar TyConBndrVis]
bad_tcbs) = ((VarSet, [VarBndr TyCoVar TyConBndrVis])
-> VarBndr TyCoVar TyConBndrVis
-> (VarSet, [VarBndr TyCoVar TyConBndrVis]))
-> (VarSet, [VarBndr TyCoVar TyConBndrVis])
-> [VarBndr TyCoVar TyConBndrVis]
-> (VarSet, [VarBndr TyCoVar TyConBndrVis])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (VarSet, [VarBndr TyCoVar TyConBndrVis])
-> VarBndr TyCoVar TyConBndrVis
-> (VarSet, [VarBndr TyCoVar TyConBndrVis])
add_one ([TyCoVar] -> VarSet
mkVarSet [TyCoVar]
tvs, []) [VarBndr TyCoVar TyConBndrVis]
tcbs
add_one :: (TyVarSet, [TyConBinder])
-> TyConBinder -> (TyVarSet, [TyConBinder])
add_one :: (VarSet, [VarBndr TyCoVar TyConBndrVis])
-> VarBndr TyCoVar TyConBndrVis
-> (VarSet, [VarBndr TyCoVar TyConBndrVis])
add_one (bad_bndrs :: VarSet
bad_bndrs, acc :: [VarBndr TyCoVar TyConBndrVis]
acc) tvb :: VarBndr TyCoVar TyConBndrVis
tvb
| VarSet
fkvs VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
bad_bndrs = (VarSet
bad', VarBndr TyCoVar TyConBndrVis
tvb VarBndr TyCoVar TyConBndrVis
-> [VarBndr TyCoVar TyConBndrVis] -> [VarBndr TyCoVar TyConBndrVis]
forall a. a -> [a] -> [a]
: [VarBndr TyCoVar TyConBndrVis]
acc)
| Bool
otherwise = (VarSet
bad', [VarBndr TyCoVar TyConBndrVis]
acc)
where
tv :: TyCoVar
tv = VarBndr TyCoVar TyConBndrVis -> TyCoVar
forall tv argf. VarBndr tv argf -> tv
binderVar VarBndr TyCoVar TyConBndrVis
tvb
fkvs :: VarSet
fkvs = Type -> VarSet
tyCoVarsOfType (TyCoVar -> Type
tyVarKind TyCoVar
tv)
bad' :: VarSet
bad' = VarSet
bad_bndrs VarSet -> TyCoVar -> VarSet
`delVarSet` TyCoVar
tv
inferred_tvs :: [TyCoVar]
inferred_tvs = [ VarBndr TyCoVar TyConBndrVis -> TyCoVar
forall tv argf. VarBndr tv argf -> tv
binderVar VarBndr TyCoVar TyConBndrVis
tcb
| VarBndr TyCoVar TyConBndrVis
tcb <- [VarBndr TyCoVar TyConBndrVis]
tcbs, ArgFlag
Inferred ArgFlag -> ArgFlag -> Bool
forall a. Eq a => a -> a -> Bool
== VarBndr TyCoVar TyConBndrVis -> ArgFlag
tyConBinderArgFlag VarBndr TyCoVar TyConBndrVis
tcb ]
specified_tvs :: [TyCoVar]
specified_tvs = [ VarBndr TyCoVar TyConBndrVis -> TyCoVar
forall tv argf. VarBndr tv argf -> tv
binderVar VarBndr TyCoVar TyConBndrVis
tcb
| VarBndr TyCoVar TyConBndrVis
tcb <- [VarBndr TyCoVar TyConBndrVis]
tcbs, ArgFlag
Specified ArgFlag -> ArgFlag -> Bool
forall a. Eq a => a -> a -> Bool
== VarBndr TyCoVar TyConBndrVis -> ArgFlag
tyConBinderArgFlag VarBndr TyCoVar TyConBndrVis
tcb ]
pp_inf :: SDoc
pp_inf = SDoc -> SDoc
parens (String -> SDoc
text "namely:" SDoc -> SDoc -> SDoc
<+> [TyCoVar] -> SDoc
pprTyVars [TyCoVar]
inferred_tvs)
pp_spec :: SDoc
pp_spec = SDoc -> SDoc
parens (String -> SDoc
text "namely:" SDoc -> SDoc -> SDoc
<+> [TyCoVar] -> SDoc
pprTyVars [TyCoVar]
specified_tvs)
extra :: SDoc
extra
| [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
inferred_tvs Bool -> Bool -> Bool
&& [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
specified_tvs
= SDoc
empty
| [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
inferred_tvs
= SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "NB: Specified variables")
2 ([SDoc] -> SDoc
sep [SDoc
pp_spec, String -> SDoc
text "always come first"])
| [TyCoVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TyCoVar]
specified_tvs
= SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "NB: Inferred variables")
2 ([SDoc] -> SDoc
sep [SDoc
pp_inf, String -> SDoc
text "always come first"])
| Bool
otherwise
= SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "NB: Inferred variables")
2 ([SDoc] -> SDoc
vcat [ [SDoc] -> SDoc
sep [ SDoc
pp_inf, String -> SDoc
text "always come first"]
, [SDoc] -> SDoc
sep [String -> SDoc
text "then Specified variables", SDoc
pp_spec]])
fvType :: Type -> [TyCoVar]
fvType :: Type -> [TyCoVar]
fvType ty :: Type
ty | Just exp_ty :: Type
exp_ty <- Type -> Maybe Type
tcView Type
ty = Type -> [TyCoVar]
fvType Type
exp_ty
fvType (TyVarTy tv :: TyCoVar
tv) = [TyCoVar
tv]
fvType (TyConApp _ tys :: [Type]
tys) = [Type] -> [TyCoVar]
fvTypes [Type]
tys
fvType (LitTy {}) = []
fvType (AppTy fun :: Type
fun arg :: Type
arg) = Type -> [TyCoVar]
fvType Type
fun [TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. [a] -> [a] -> [a]
++ Type -> [TyCoVar]
fvType Type
arg
fvType (FunTy arg :: Type
arg res :: Type
res) = Type -> [TyCoVar]
fvType Type
arg [TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. [a] -> [a] -> [a]
++ Type -> [TyCoVar]
fvType Type
res
fvType (ForAllTy (Bndr tv :: TyCoVar
tv _) ty :: Type
ty)
= Type -> [TyCoVar]
fvType (TyCoVar -> Type
tyVarKind TyCoVar
tv) [TyCoVar] -> [TyCoVar] -> [TyCoVar]
forall a. [a] -> [a] -> [a]
++
(TyCoVar -> Bool) -> [TyCoVar] -> [TyCoVar]
forall a. (a -> Bool) -> [a] -> [a]
filter (TyCoVar -> TyCoVar -> Bool
forall a. Eq a => a -> a -> Bool
/= TyCoVar
tv) (Type -> [TyCoVar]
fvType Type
ty)
fvType (CastTy ty :: Type
ty _) = Type -> [TyCoVar]
fvType Type
ty
fvType (CoercionTy {}) = []
fvTypes :: [Type] -> [TyVar]
fvTypes :: [Type] -> [TyCoVar]
fvTypes tys :: [Type]
tys = [[TyCoVar]] -> [TyCoVar]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((Type -> [TyCoVar]) -> [Type] -> [[TyCoVar]]
forall a b. (a -> b) -> [a] -> [b]
map Type -> [TyCoVar]
fvType [Type]
tys)
sizeType :: Type -> Int
sizeType :: Type -> Int
sizeType ty :: Type
ty | Just exp_ty :: Type
exp_ty <- Type -> Maybe Type
tcView Type
ty = Type -> Int
sizeType Type
exp_ty
sizeType (TyVarTy {}) = 1
sizeType (TyConApp tc :: TyCon
tc tys :: [Type]
tys) = 1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ TyCon -> [Type] -> Int
sizeTyConAppArgs TyCon
tc [Type]
tys
sizeType (LitTy {}) = 1
sizeType (AppTy fun :: Type
fun arg :: Type
arg) = Type -> Int
sizeType Type
fun Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
sizeType Type
arg
sizeType (FunTy arg :: Type
arg res :: Type
res) = Type -> Int
sizeType Type
arg Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Type -> Int
sizeType Type
res Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1
sizeType (ForAllTy _ ty :: Type
ty) = Type -> Int
sizeType Type
ty
sizeType (CastTy ty :: Type
ty _) = Type -> Int
sizeType Type
ty
sizeType (CoercionTy _) = 0
sizeTypes :: [Type] -> Int
sizeTypes :: [Type] -> Int
sizeTypes = (Type -> Int -> Int) -> Int -> [Type] -> Int
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (Int -> Int -> Int) -> (Type -> Int) -> Type -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Int
sizeType) 0
sizeTyConAppArgs :: TyCon -> [Type] -> Int
sizeTyConAppArgs :: TyCon -> [Type] -> Int
sizeTyConAppArgs _tc :: TyCon
_tc tys :: [Type]
tys = [Type] -> Int
sizeTypes [Type]
tys
sizePred :: PredType -> Int
sizePred :: Type -> Int
sizePred ty :: Type
ty = Type -> Int
goClass Type
ty
where
goClass :: Type -> Int
goClass p :: Type
p = PredTree -> Int
go (Type -> PredTree
classifyPredType Type
p)
go :: PredTree -> Int
go (ClassPred cls :: Class
cls tys' :: [Type]
tys')
| Class -> Bool
isTerminatingClass Class
cls = 0
| Bool
otherwise = [Type] -> Int
sizeTypes (TyCon -> [Type] -> [Type]
filterOutInvisibleTypes (Class -> TyCon
classTyCon Class
cls) [Type]
tys')
go (EqPred {}) = 0
go (IrredPred ty :: Type
ty) = Type -> Int
sizeType Type
ty
go (ForAllPred _ _ pred :: Type
pred) = Type -> Int
goClass Type
pred
isTerminatingClass :: Class -> Bool
isTerminatingClass :: Class -> Bool
isTerminatingClass cls :: Class
cls
= Class -> Bool
isIPClass Class
cls
Bool -> Bool -> Bool
|| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
typeableClassKey
Bool -> Bool -> Bool
|| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
coercibleTyConKey
Bool -> Bool -> Bool
|| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
eqTyConKey
Bool -> Bool -> Bool
|| Class
cls Class -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
heqTyConKey
ppr_tidy :: TidyEnv -> Type -> SDoc
ppr_tidy :: TidyEnv -> Type -> SDoc
ppr_tidy env :: TidyEnv
env ty :: Type
ty = Type -> SDoc
pprType (TidyEnv -> Type -> Type
tidyType TidyEnv
env Type
ty)
allDistinctTyVars :: TyVarSet -> [KindOrType] -> Bool
allDistinctTyVars :: VarSet -> [Type] -> Bool
allDistinctTyVars _ [] = Bool
True
allDistinctTyVars tkvs :: VarSet
tkvs (ty :: Type
ty : tys :: [Type]
tys)
= case Type -> Maybe TyCoVar
getTyVar_maybe Type
ty of
Nothing -> Bool
False
Just tv :: TyCoVar
tv | TyCoVar
tv TyCoVar -> VarSet -> Bool
`elemVarSet` VarSet
tkvs -> Bool
False
| Bool
otherwise -> VarSet -> [Type] -> Bool
allDistinctTyVars (VarSet
tkvs VarSet -> TyCoVar -> VarSet
`extendVarSet` TyCoVar
tv) [Type]
tys