{-# LANGUAGE CPP, GADTs #-}
module FamInst (
FamInstEnvs, tcGetFamInstEnvs,
checkFamInstConsistency, tcExtendLocalFamInstEnv,
tcLookupDataFamInst, tcLookupDataFamInst_maybe,
tcInstNewTyCon_maybe, tcTopNormaliseNewTypeTF_maybe,
newFamInst,
makeInjectivityErrors, injTyVarsOfType, injTyVarsOfTypes
) where
import GhcPrelude
import HscTypes
import FamInstEnv
import InstEnv( roughMatchTcs )
import Coercion
import CoreLint
import TcEvidence
import LoadIface
import TcRnMonad
import SrcLoc
import TyCon
import TcType
import CoAxiom
import DynFlags
import Module
import Outputable
import Util
import RdrName
import DataCon ( dataConName )
import Maybes
import Type
import TyCoRep
import TcMType
import Name
import Pair
import Panic
import VarSet
import Bag( Bag, unionBags, unitBag )
import Control.Monad
#include "HsVersions.h"
newFamInst :: FamFlavor -> CoAxiom Unbranched -> TcM FamInst
newFamInst :: FamFlavor -> CoAxiom Unbranched -> TcM FamInst
newFamInst flavor :: FamFlavor
flavor axiom :: CoAxiom Unbranched
axiom@(CoAxiom { co_ax_tc :: forall (br :: BranchFlag). CoAxiom br -> TyCon
co_ax_tc = TyCon
fam_tc })
= ASSERT2( tyCoVarsOfTypes lhs `subVarSet` tcv_set, text "lhs" <+> pp_ax )
ASSERT2( tyCoVarsOfType rhs `subVarSet` tcv_set, text "rhs" <+> pp_ax )
ASSERT2( lhs_kind `eqType` rhs_kind, text "kind" <+> pp_ax $$ ppr lhs_kind $$ ppr rhs_kind )
do { (subst :: TCvSubst
subst, tvs' :: [TyVar]
tvs') <- [TyVar] -> TcM (TCvSubst, [TyVar])
freshenTyVarBndrs [TyVar]
tvs
; (subst :: TCvSubst
subst, cvs' :: [TyVar]
cvs') <- TCvSubst -> [TyVar] -> TcM (TCvSubst, [TyVar])
freshenCoVarBndrsX TCvSubst
subst [TyVar]
cvs
; DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let lhs' :: [Type]
lhs' = HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys TCvSubst
subst [Type]
lhs
rhs' :: Type
rhs' = HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst Type
rhs
tcvs' :: [TyVar]
tcvs' = [TyVar]
tvs' [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
cvs'
; TcRn () -> TcRn () -> TcRn ()
forall r. TcRn r -> TcRn r -> TcRn r
ifErrsM (() -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$
Bool -> TcRn () -> TcRn ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_DoCoreLinting DynFlags
dflags) (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$
case DynFlags -> [TyVar] -> [Type] -> Maybe SDoc
lintTypes DynFlags
dflags [TyVar]
tcvs' (Type
rhs'Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
:[Type]
lhs') of
Nothing -> () -> TcRn ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just fail_msg :: SDoc
fail_msg -> String -> SDoc -> TcRn ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic "Core Lint error" ([SDoc] -> SDoc
vcat [ SDoc
fail_msg
, TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
fam_tc
, TCvSubst -> SDoc
forall a. Outputable a => a -> SDoc
ppr TCvSubst
subst
, [TyVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVar]
tvs'
, [TyVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVar]
cvs'
, [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
lhs'
, Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
rhs' ])
; FamInst -> TcM FamInst
forall (m :: * -> *) a. Monad m => a -> m a
return (FamInst :: CoAxiom Unbranched
-> FamFlavor
-> Name
-> [Maybe Name]
-> [TyVar]
-> [TyVar]
-> [Type]
-> Type
-> FamInst
FamInst { fi_fam :: Name
fi_fam = TyCon -> Name
tyConName TyCon
fam_tc
, fi_flavor :: FamFlavor
fi_flavor = FamFlavor
flavor
, fi_tcs :: [Maybe Name]
fi_tcs = [Type] -> [Maybe Name]
roughMatchTcs [Type]
lhs
, fi_tvs :: [TyVar]
fi_tvs = [TyVar]
tvs'
, fi_cvs :: [TyVar]
fi_cvs = [TyVar]
cvs'
, fi_tys :: [Type]
fi_tys = [Type]
lhs'
, fi_rhs :: Type
fi_rhs = Type
rhs'
, fi_axiom :: CoAxiom Unbranched
fi_axiom = CoAxiom Unbranched
axiom }) }
where
lhs_kind :: Type
lhs_kind = HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind (TyCon -> [Type] -> Type
mkTyConApp TyCon
fam_tc [Type]
lhs)
rhs_kind :: Type
rhs_kind = HasDebugCallStack => Type -> Type
Type -> Type
tcTypeKind Type
rhs
tcv_set :: TyCoVarSet
tcv_set = [TyVar] -> TyCoVarSet
mkVarSet ([TyVar]
tvs [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
cvs)
pp_ax :: SDoc
pp_ax = CoAxiom Unbranched -> SDoc
forall (br :: BranchFlag). CoAxiom br -> SDoc
pprCoAxiom CoAxiom Unbranched
axiom
CoAxBranch { cab_tvs :: CoAxBranch -> [TyVar]
cab_tvs = [TyVar]
tvs
, cab_cvs :: CoAxBranch -> [TyVar]
cab_cvs = [TyVar]
cvs
, cab_lhs :: CoAxBranch -> [Type]
cab_lhs = [Type]
lhs
, cab_rhs :: CoAxBranch -> Type
cab_rhs = Type
rhs } = CoAxiom Unbranched -> CoAxBranch
coAxiomSingleBranch CoAxiom Unbranched
axiom
checkFamInstConsistency :: [Module] -> TcM ()
checkFamInstConsistency :: [Module] -> TcRn ()
checkFamInstConsistency directlyImpMods :: [Module]
directlyImpMods
= do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; (eps :: ExternalPackageState
eps, hpt :: HomePackageTable
hpt) <- TcRnIf TcGblEnv TcLclEnv (ExternalPackageState, HomePackageTable)
forall gbl lcl.
TcRnIf gbl lcl (ExternalPackageState, HomePackageTable)
getEpsAndHpt
; String -> SDoc -> TcRn ()
traceTc "checkFamInstConsistency" ([Module] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Module]
directlyImpMods)
; let {
modIface :: Module -> ModIface
modIface mod :: Module
mod =
case DynFlags
-> HomePackageTable
-> PackageIfaceTable
-> Module
-> Maybe ModIface
lookupIfaceByModule DynFlags
dflags HomePackageTable
hpt (ExternalPackageState -> PackageIfaceTable
eps_PIT ExternalPackageState
eps) Module
mod of
Nothing -> String -> SDoc -> ModIface
forall a. String -> SDoc -> a
panicDoc "FamInst.checkFamInstConsistency"
(Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod SDoc -> SDoc -> SDoc
$$ HomePackageTable -> SDoc
pprHPT HomePackageTable
hpt)
Just iface :: ModIface
iface -> ModIface
iface
; modConsistent :: Module -> [Module]
; modConsistent :: Module -> [Module]
modConsistent mod :: Module
mod =
if ModIface -> Bool
mi_finsts (Module -> ModIface
modIface Module
mod) then Module
modModule -> [Module] -> [Module]
forall a. a -> [a] -> [a]
:[Module]
deps else [Module]
deps
where
deps :: [Module]
deps = Dependencies -> [Module]
dep_finsts (Dependencies -> [Module])
-> (Module -> Dependencies) -> Module -> [Module]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModIface -> Dependencies
mi_deps (ModIface -> Dependencies)
-> (Module -> ModIface) -> Module -> Dependencies
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Module -> ModIface
modIface (Module -> [Module]) -> Module -> [Module]
forall a b. (a -> b) -> a -> b
$ Module
mod
; hmiModule :: HomeModInfo -> Module
hmiModule = ModIface -> Module
mi_module (ModIface -> Module)
-> (HomeModInfo -> ModIface) -> HomeModInfo -> Module
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HomeModInfo -> ModIface
hm_iface
; hmiFamInstEnv :: HomeModInfo -> FamInstEnv
hmiFamInstEnv = FamInstEnv -> [FamInst] -> FamInstEnv
extendFamInstEnvList FamInstEnv
emptyFamInstEnv
([FamInst] -> FamInstEnv)
-> (HomeModInfo -> [FamInst]) -> HomeModInfo -> FamInstEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModDetails -> [FamInst]
md_fam_insts (ModDetails -> [FamInst])
-> (HomeModInfo -> ModDetails) -> HomeModInfo -> [FamInst]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HomeModInfo -> ModDetails
hm_details
; hpt_fam_insts :: ModuleEnv FamInstEnv
hpt_fam_insts = [(Module, FamInstEnv)] -> ModuleEnv FamInstEnv
forall a. [(Module, a)] -> ModuleEnv a
mkModuleEnv [ (HomeModInfo -> Module
hmiModule HomeModInfo
hmi, HomeModInfo -> FamInstEnv
hmiFamInstEnv HomeModInfo
hmi)
| HomeModInfo
hmi <- HomePackageTable -> [HomeModInfo]
eltsHpt HomePackageTable
hpt]
}
; ModuleEnv FamInstEnv -> (Module -> [Module]) -> [Module] -> TcRn ()
checkMany ModuleEnv FamInstEnv
hpt_fam_insts Module -> [Module]
modConsistent [Module]
directlyImpMods
}
where
checkMany
:: ModuleEnv FamInstEnv
-> (Module -> [Module])
-> [Module]
-> TcM ()
checkMany :: ModuleEnv FamInstEnv -> (Module -> [Module]) -> [Module] -> TcRn ()
checkMany hpt_fam_insts :: ModuleEnv FamInstEnv
hpt_fam_insts modConsistent :: Module -> [Module]
modConsistent mods :: [Module]
mods = [Module] -> ModuleSet -> [Module] -> TcRn ()
go [] ModuleSet
emptyModuleSet [Module]
mods
where
go :: [Module]
-> ModuleSet
-> [Module]
-> TcM ()
go :: [Module] -> ModuleSet -> [Module] -> TcRn ()
go _ _ [] = () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
go consistent :: [Module]
consistent consistent_set :: ModuleSet
consistent_set (mod :: Module
mod:mods :: [Module]
mods) = do
[TcRn ()] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_
[ ModuleEnv FamInstEnv -> Module -> Module -> TcRn ()
check ModuleEnv FamInstEnv
hpt_fam_insts Module
m1 Module
m2
| Module
m1 <- [Module]
to_check_from_mod
, Module
m2 <- [Module]
to_check_from_consistent
]
[Module] -> ModuleSet -> [Module] -> TcRn ()
go [Module]
consistent' ModuleSet
consistent_set' [Module]
mods
where
mod_deps_consistent :: [Module]
mod_deps_consistent = Module -> [Module]
modConsistent Module
mod
mod_deps_consistent_set :: ModuleSet
mod_deps_consistent_set = [Module] -> ModuleSet
mkModuleSet [Module]
mod_deps_consistent
consistent' :: [Module]
consistent' = [Module]
to_check_from_mod [Module] -> [Module] -> [Module]
forall a. [a] -> [a] -> [a]
++ [Module]
consistent
consistent_set' :: ModuleSet
consistent_set' =
ModuleSet -> [Module] -> ModuleSet
extendModuleSetList ModuleSet
consistent_set [Module]
to_check_from_mod
to_check_from_consistent :: [Module]
to_check_from_consistent =
(Module -> Bool) -> [Module] -> [Module]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (Module -> ModuleSet -> Bool
`elemModuleSet` ModuleSet
mod_deps_consistent_set) [Module]
consistent
to_check_from_mod :: [Module]
to_check_from_mod =
(Module -> Bool) -> [Module] -> [Module]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (Module -> ModuleSet -> Bool
`elemModuleSet` ModuleSet
consistent_set) [Module]
mod_deps_consistent
check :: ModuleEnv FamInstEnv -> Module -> Module -> TcRn ()
check hpt_fam_insts :: ModuleEnv FamInstEnv
hpt_fam_insts m1 :: Module
m1 m2 :: Module
m2
= do { FamInstEnv
env1' <- ModuleEnv FamInstEnv -> Module -> TcM FamInstEnv
getFamInsts ModuleEnv FamInstEnv
hpt_fam_insts Module
m1
; FamInstEnv
env2' <- ModuleEnv FamInstEnv -> Module -> TcM FamInstEnv
getFamInsts ModuleEnv FamInstEnv
hpt_fam_insts Module
m2
; let sizeE1 :: Int
sizeE1 = FamInstEnv -> Int
famInstEnvSize FamInstEnv
env1'
sizeE2 :: Int
sizeE2 = FamInstEnv -> Int
famInstEnvSize FamInstEnv
env2'
(env1 :: FamInstEnv
env1, env2 :: FamInstEnv
env2) = if Int
sizeE1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sizeE2 then (FamInstEnv
env1', FamInstEnv
env2')
else (FamInstEnv
env2', FamInstEnv
env1')
; let check_now :: [FamInst]
check_now = FamInstEnv -> [FamInst]
famInstEnvElts FamInstEnv
env1
; (FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool)
-> [FamInst] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((FamInstEnv, FamInstEnv)
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool
checkForConflicts (FamInstEnv
emptyFamInstEnv, FamInstEnv
env2)) [FamInst]
check_now
; (FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool)
-> [FamInst] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((FamInstEnv, FamInstEnv)
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool
checkForInjectivityConflicts (FamInstEnv
emptyFamInstEnv,FamInstEnv
env2)) [FamInst]
check_now
}
getFamInsts :: ModuleEnv FamInstEnv -> Module -> TcM FamInstEnv
getFamInsts :: ModuleEnv FamInstEnv -> Module -> TcM FamInstEnv
getFamInsts hpt_fam_insts :: ModuleEnv FamInstEnv
hpt_fam_insts mod :: Module
mod
| Just env :: FamInstEnv
env <- ModuleEnv FamInstEnv -> Module -> Maybe FamInstEnv
forall a. ModuleEnv a -> Module -> Maybe a
lookupModuleEnv ModuleEnv FamInstEnv
hpt_fam_insts Module
mod = FamInstEnv -> TcM FamInstEnv
forall (m :: * -> *) a. Monad m => a -> m a
return FamInstEnv
env
| Bool
otherwise = do { ModIface
_ <- IfG ModIface -> TcRn ModIface
forall a. IfG a -> TcRn a
initIfaceTcRn (SDoc -> Module -> IfG ModIface
forall lcl. SDoc -> Module -> IfM lcl ModIface
loadSysInterface SDoc
doc Module
mod)
; ExternalPackageState
eps <- TcRnIf TcGblEnv TcLclEnv ExternalPackageState
forall gbl lcl. TcRnIf gbl lcl ExternalPackageState
getEps
; FamInstEnv -> TcM FamInstEnv
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Maybe FamInstEnv -> FamInstEnv
forall a. HasCallStack => String -> Maybe a -> a
expectJust "checkFamInstConsistency" (Maybe FamInstEnv -> FamInstEnv) -> Maybe FamInstEnv -> FamInstEnv
forall a b. (a -> b) -> a -> b
$
ModuleEnv FamInstEnv -> Module -> Maybe FamInstEnv
forall a. ModuleEnv a -> Module -> Maybe a
lookupModuleEnv (ExternalPackageState -> ModuleEnv FamInstEnv
eps_mod_fam_inst_env ExternalPackageState
eps) Module
mod) }
where
doc :: SDoc
doc = Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "is a family-instance module"
tcInstNewTyCon_maybe :: TyCon -> [TcType] -> Maybe (TcType, TcCoercion)
tcInstNewTyCon_maybe :: TyCon -> [Type] -> Maybe (Type, TcCoercion)
tcInstNewTyCon_maybe = TyCon -> [Type] -> Maybe (Type, TcCoercion)
instNewTyCon_maybe
tcLookupDataFamInst :: FamInstEnvs -> TyCon -> [TcType]
-> (TyCon, [TcType], Coercion)
tcLookupDataFamInst :: (FamInstEnv, FamInstEnv)
-> TyCon -> [Type] -> (TyCon, [Type], TcCoercion)
tcLookupDataFamInst fam_inst_envs :: (FamInstEnv, FamInstEnv)
fam_inst_envs tc :: TyCon
tc tc_args :: [Type]
tc_args
| Just (rep_tc :: TyCon
rep_tc, rep_args :: [Type]
rep_args, co :: TcCoercion
co)
<- (FamInstEnv, FamInstEnv)
-> TyCon -> [Type] -> Maybe (TyCon, [Type], TcCoercion)
tcLookupDataFamInst_maybe (FamInstEnv, FamInstEnv)
fam_inst_envs TyCon
tc [Type]
tc_args
= (TyCon
rep_tc, [Type]
rep_args, TcCoercion
co)
| Bool
otherwise
= (TyCon
tc, [Type]
tc_args, Type -> TcCoercion
mkRepReflCo (TyCon -> [Type] -> Type
mkTyConApp TyCon
tc [Type]
tc_args))
tcLookupDataFamInst_maybe :: FamInstEnvs -> TyCon -> [TcType]
-> Maybe (TyCon, [TcType], Coercion)
tcLookupDataFamInst_maybe :: (FamInstEnv, FamInstEnv)
-> TyCon -> [Type] -> Maybe (TyCon, [Type], TcCoercion)
tcLookupDataFamInst_maybe fam_inst_envs :: (FamInstEnv, FamInstEnv)
fam_inst_envs tc :: TyCon
tc tc_args :: [Type]
tc_args
| TyCon -> Bool
isDataFamilyTyCon TyCon
tc
, match :: FamInstMatch
match : _ <- (FamInstEnv, FamInstEnv) -> TyCon -> [Type] -> [FamInstMatch]
lookupFamInstEnv (FamInstEnv, FamInstEnv)
fam_inst_envs TyCon
tc [Type]
tc_args
, FamInstMatch { fim_instance :: FamInstMatch -> FamInst
fim_instance = rep_fam :: FamInst
rep_fam@(FamInst { fi_axiom :: FamInst -> CoAxiom Unbranched
fi_axiom = CoAxiom Unbranched
ax
, fi_cvs :: FamInst -> [TyVar]
fi_cvs = [TyVar]
cvs })
, fim_tys :: FamInstMatch -> [Type]
fim_tys = [Type]
rep_args
, fim_cos :: FamInstMatch -> [TcCoercion]
fim_cos = [TcCoercion]
rep_cos } <- FamInstMatch
match
, let rep_tc :: TyCon
rep_tc = FamInst -> TyCon
dataFamInstRepTyCon FamInst
rep_fam
co :: TcCoercion
co = Role -> CoAxiom Unbranched -> [Type] -> [TcCoercion] -> TcCoercion
mkUnbranchedAxInstCo Role
Representational CoAxiom Unbranched
ax [Type]
rep_args
([TyVar] -> [TcCoercion]
mkCoVarCos [TyVar]
cvs)
= ASSERT( null rep_cos )
(TyCon, [Type], TcCoercion) -> Maybe (TyCon, [Type], TcCoercion)
forall a. a -> Maybe a
Just (TyCon
rep_tc, [Type]
rep_args, TcCoercion
co)
| Bool
otherwise
= Maybe (TyCon, [Type], TcCoercion)
forall a. Maybe a
Nothing
tcTopNormaliseNewTypeTF_maybe :: FamInstEnvs
-> GlobalRdrEnv
-> Type
-> Maybe ((Bag GlobalRdrElt, TcCoercion), Type)
tcTopNormaliseNewTypeTF_maybe :: (FamInstEnv, FamInstEnv)
-> GlobalRdrEnv
-> Type
-> Maybe ((Bag GlobalRdrElt, TcCoercion), Type)
tcTopNormaliseNewTypeTF_maybe faminsts :: (FamInstEnv, FamInstEnv)
faminsts rdr_env :: GlobalRdrEnv
rdr_env ty :: Type
ty
= NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
-> ((Bag GlobalRdrElt, TcCoercion)
-> (Bag GlobalRdrElt, TcCoercion)
-> (Bag GlobalRdrElt, TcCoercion))
-> Type
-> Maybe ((Bag GlobalRdrElt, TcCoercion), Type)
forall ev.
NormaliseStepper ev -> (ev -> ev -> ev) -> Type -> Maybe (ev, Type)
topNormaliseTypeX NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
stepper (Bag GlobalRdrElt, TcCoercion)
-> (Bag GlobalRdrElt, TcCoercion) -> (Bag GlobalRdrElt, TcCoercion)
plus Type
ty
where
plus :: (Bag GlobalRdrElt, TcCoercion) -> (Bag GlobalRdrElt, TcCoercion)
-> (Bag GlobalRdrElt, TcCoercion)
plus :: (Bag GlobalRdrElt, TcCoercion)
-> (Bag GlobalRdrElt, TcCoercion) -> (Bag GlobalRdrElt, TcCoercion)
plus (gres1 :: Bag GlobalRdrElt
gres1, co1 :: TcCoercion
co1) (gres2 :: Bag GlobalRdrElt
gres2, co2 :: TcCoercion
co2) = ( Bag GlobalRdrElt
gres1 Bag GlobalRdrElt -> Bag GlobalRdrElt -> Bag GlobalRdrElt
forall a. Bag a -> Bag a -> Bag a
`unionBags` Bag GlobalRdrElt
gres2
, TcCoercion
co1 TcCoercion -> TcCoercion -> TcCoercion
`mkTransCo` TcCoercion
co2 )
stepper :: NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
stepper :: NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
stepper = NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
unwrap_newtype NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
-> NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
-> NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
forall ev.
NormaliseStepper ev -> NormaliseStepper ev -> NormaliseStepper ev
`composeSteppers` NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
unwrap_newtype_instance
unwrap_newtype_instance :: NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
unwrap_newtype_instance rec_nts :: RecTcChecker
rec_nts tc :: TyCon
tc tys :: [Type]
tys
| Just (tc' :: TyCon
tc', tys' :: [Type]
tys', co :: TcCoercion
co) <- (FamInstEnv, FamInstEnv)
-> TyCon -> [Type] -> Maybe (TyCon, [Type], TcCoercion)
tcLookupDataFamInst_maybe (FamInstEnv, FamInstEnv)
faminsts TyCon
tc [Type]
tys
= ((Bag GlobalRdrElt, TcCoercion) -> (Bag GlobalRdrElt, TcCoercion))
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
forall ev1 ev2.
(ev1 -> ev2) -> NormaliseStepResult ev1 -> NormaliseStepResult ev2
mapStepResult (\(gres :: Bag GlobalRdrElt
gres, co1 :: TcCoercion
co1) -> (Bag GlobalRdrElt
gres, TcCoercion
co TcCoercion -> TcCoercion -> TcCoercion
`mkTransCo` TcCoercion
co1)) (NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion))
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
forall a b. (a -> b) -> a -> b
$
NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
unwrap_newtype RecTcChecker
rec_nts TyCon
tc' [Type]
tys'
| Bool
otherwise = NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
forall ev. NormaliseStepResult ev
NS_Done
unwrap_newtype :: NormaliseStepper (Bag GlobalRdrElt, TcCoercion)
unwrap_newtype rec_nts :: RecTcChecker
rec_nts tc :: TyCon
tc tys :: [Type]
tys
| Just con :: DataCon
con <- TyCon -> Maybe DataCon
newTyConDataCon_maybe TyCon
tc
, Just gre :: GlobalRdrElt
gre <- GlobalRdrEnv -> Name -> Maybe GlobalRdrElt
lookupGRE_Name GlobalRdrEnv
rdr_env (DataCon -> Name
dataConName DataCon
con)
= (TcCoercion -> (Bag GlobalRdrElt, TcCoercion))
-> NormaliseStepResult TcCoercion
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
forall ev1 ev2.
(ev1 -> ev2) -> NormaliseStepResult ev1 -> NormaliseStepResult ev2
mapStepResult (\co :: TcCoercion
co -> (GlobalRdrElt -> Bag GlobalRdrElt
forall a. a -> Bag a
unitBag GlobalRdrElt
gre, TcCoercion
co)) (NormaliseStepResult TcCoercion
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion))
-> NormaliseStepResult TcCoercion
-> NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
forall a b. (a -> b) -> a -> b
$
NormaliseStepper TcCoercion
unwrapNewTypeStepper RecTcChecker
rec_nts TyCon
tc [Type]
tys
| Bool
otherwise
= NormaliseStepResult (Bag GlobalRdrElt, TcCoercion)
forall ev. NormaliseStepResult ev
NS_Done
tcExtendLocalFamInstEnv :: [FamInst] -> TcM a -> TcM a
tcExtendLocalFamInstEnv :: [FamInst] -> TcM a -> TcM a
tcExtendLocalFamInstEnv [] thing_inside :: TcM a
thing_inside = TcM a
thing_inside
tcExtendLocalFamInstEnv fam_insts :: [FamInst]
fam_insts thing_inside :: TcM a
thing_inside
= do {
[FamInst] -> TcRn ()
loadDependentFamInstModules [FamInst]
fam_insts
; TcGblEnv
env <- TcRnIf TcGblEnv TcLclEnv TcGblEnv
forall gbl lcl. TcRnIf gbl lcl gbl
getGblEnv
; (inst_env' :: FamInstEnv
inst_env', fam_insts' :: [FamInst]
fam_insts') <- ((FamInstEnv, [FamInst])
-> FamInst
-> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst]))
-> (FamInstEnv, [FamInst])
-> [FamInst]
-> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst])
forall (m :: * -> *) a b.
Monad m =>
(a -> b -> m a) -> a -> [b] -> m a
foldlM (FamInstEnv, [FamInst])
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst])
addLocalFamInst
(TcGblEnv -> FamInstEnv
tcg_fam_inst_env TcGblEnv
env, TcGblEnv -> [FamInst]
tcg_fam_insts TcGblEnv
env)
[FamInst]
fam_insts
; let env' :: TcGblEnv
env' = TcGblEnv
env { tcg_fam_insts :: [FamInst]
tcg_fam_insts = [FamInst]
fam_insts'
, tcg_fam_inst_env :: FamInstEnv
tcg_fam_inst_env = FamInstEnv
inst_env' }
; TcGblEnv -> TcM a -> TcM a
forall gbl lcl a. gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
setGblEnv TcGblEnv
env' TcM a
thing_inside
}
loadDependentFamInstModules :: [FamInst] -> TcM ()
loadDependentFamInstModules :: [FamInst] -> TcRn ()
loadDependentFamInstModules fam_insts :: [FamInst]
fam_insts
= do { TcGblEnv
env <- TcRnIf TcGblEnv TcLclEnv TcGblEnv
forall gbl lcl. TcRnIf gbl lcl gbl
getGblEnv
; let this_mod :: Module
this_mod = TcGblEnv -> Module
tcg_mod TcGblEnv
env
imports :: ImportAvails
imports = TcGblEnv -> ImportAvails
tcg_imports TcGblEnv
env
want_module :: Module -> Bool
want_module mod :: Module
mod
| Module
mod Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
== Module
this_mod = Bool
False
| Bool
home_fams_only = Module -> UnitId
moduleUnitId Module
mod UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== Module -> UnitId
moduleUnitId Module
this_mod
| Bool
otherwise = Bool
True
home_fams_only :: Bool
home_fams_only = (FamInst -> Bool) -> [FamInst] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Module -> Name -> Bool
nameIsHomePackage Module
this_mod (Name -> Bool) -> (FamInst -> Name) -> FamInst -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FamInst -> Name
fi_fam) [FamInst]
fam_insts
; SDoc -> [Module] -> TcRn ()
loadModuleInterfaces (String -> SDoc
text "Loading family-instance modules") ([Module] -> TcRn ()) -> [Module] -> TcRn ()
forall a b. (a -> b) -> a -> b
$
(Module -> Bool) -> [Module] -> [Module]
forall a. (a -> Bool) -> [a] -> [a]
filter Module -> Bool
want_module (ImportAvails -> [Module]
imp_finsts ImportAvails
imports) }
addLocalFamInst :: (FamInstEnv,[FamInst])
-> FamInst
-> TcM (FamInstEnv, [FamInst])
addLocalFamInst :: (FamInstEnv, [FamInst])
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst])
addLocalFamInst (home_fie :: FamInstEnv
home_fie, my_fis :: [FamInst]
my_fis) fam_inst :: FamInst
fam_inst
= do { String -> SDoc -> TcRn ()
traceTc "addLocalFamInst" (FamInst -> SDoc
forall a. Outputable a => a -> SDoc
ppr FamInst
fam_inst)
; Module
mod <- IOEnv (Env TcGblEnv TcLclEnv) Module
forall (m :: * -> *). HasModule m => m Module
getModule
; String -> SDoc -> TcRn ()
traceTc "alfi" (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod)
; ExternalPackageState
eps <- TcRnIf TcGblEnv TcLclEnv ExternalPackageState
forall gbl lcl. TcRnIf gbl lcl ExternalPackageState
getEps
; let inst_envs :: (FamInstEnv, FamInstEnv)
inst_envs = (ExternalPackageState -> FamInstEnv
eps_fam_inst_env ExternalPackageState
eps, FamInstEnv
home_fie)
home_fie' :: FamInstEnv
home_fie' = FamInstEnv -> FamInst -> FamInstEnv
extendFamInstEnv FamInstEnv
home_fie FamInst
fam_inst
; Bool
no_conflict <- (FamInstEnv, FamInstEnv)
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool
checkForConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
; Bool
injectivity_ok <- (FamInstEnv, FamInstEnv)
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool
checkForInjectivityConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
; if Bool
no_conflict Bool -> Bool -> Bool
&& Bool
injectivity_ok then
(FamInstEnv, [FamInst])
-> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst])
forall (m :: * -> *) a. Monad m => a -> m a
return (FamInstEnv
home_fie', FamInst
fam_inst FamInst -> [FamInst] -> [FamInst]
forall a. a -> [a] -> [a]
: [FamInst]
my_fis)
else
(FamInstEnv, [FamInst])
-> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst])
forall (m :: * -> *) a. Monad m => a -> m a
return (FamInstEnv
home_fie, [FamInst]
my_fis) }
checkForConflicts :: FamInstEnvs -> FamInst -> TcM Bool
checkForConflicts :: (FamInstEnv, FamInstEnv)
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool
checkForConflicts inst_envs :: (FamInstEnv, FamInstEnv)
inst_envs fam_inst :: FamInst
fam_inst
= do { let conflicts :: [FamInstMatch]
conflicts = (FamInstEnv, FamInstEnv) -> FamInst -> [FamInstMatch]
lookupFamInstEnvConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
; String -> SDoc -> TcRn ()
traceTc "checkForConflicts" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ [FamInst] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((FamInstMatch -> FamInst) -> [FamInstMatch] -> [FamInst]
forall a b. (a -> b) -> [a] -> [b]
map FamInstMatch -> FamInst
fim_instance [FamInstMatch]
conflicts)
, FamInst -> SDoc
forall a. Outputable a => a -> SDoc
ppr FamInst
fam_inst
]
; FamInst -> [FamInstMatch] -> TcRn ()
reportConflictInstErr FamInst
fam_inst [FamInstMatch]
conflicts
; Bool -> IOEnv (Env TcGblEnv TcLclEnv) Bool
forall (m :: * -> *) a. Monad m => a -> m a
return ([FamInstMatch] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FamInstMatch]
conflicts) }
checkForInjectivityConflicts :: FamInstEnvs -> FamInst -> TcM Bool
checkForInjectivityConflicts :: (FamInstEnv, FamInstEnv)
-> FamInst -> IOEnv (Env TcGblEnv TcLclEnv) Bool
checkForInjectivityConflicts instEnvs :: (FamInstEnv, FamInstEnv)
instEnvs famInst :: FamInst
famInst
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tycon
, Injective inj :: [Bool]
inj <- TyCon -> Injectivity
tyConInjectivityInfo TyCon
tycon = do
{ let axiom :: CoAxBranch
axiom = CoAxiom Unbranched -> CoAxBranch
coAxiomSingleBranch CoAxiom Unbranched
fi_ax
conflicts :: [CoAxBranch]
conflicts = [Bool] -> (FamInstEnv, FamInstEnv) -> FamInst -> [CoAxBranch]
lookupFamInstEnvInjectivityConflicts [Bool]
inj (FamInstEnv, FamInstEnv)
instEnvs FamInst
famInst
errs :: [(SDoc, SrcSpan)]
errs = CoAxiom Unbranched
-> CoAxBranch -> [Bool] -> [CoAxBranch] -> [(SDoc, SrcSpan)]
forall (br :: BranchFlag).
CoAxiom br
-> CoAxBranch -> [Bool] -> [CoAxBranch] -> [(SDoc, SrcSpan)]
makeInjectivityErrors CoAxiom Unbranched
fi_ax CoAxBranch
axiom [Bool]
inj [CoAxBranch]
conflicts
; ((SDoc, SrcSpan) -> TcRn ()) -> [(SDoc, SrcSpan)] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(err :: SDoc
err, span :: SrcSpan
span) -> SrcSpan -> TcRn () -> TcRn ()
forall a. SrcSpan -> TcRn a -> TcRn a
setSrcSpan SrcSpan
span (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$ SDoc -> TcRn ()
addErr SDoc
err) [(SDoc, SrcSpan)]
errs
; Bool -> IOEnv (Env TcGblEnv TcLclEnv) Bool
forall (m :: * -> *) a. Monad m => a -> m a
return ([(SDoc, SrcSpan)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(SDoc, SrcSpan)]
errs)
}
| Bool
otherwise = Bool -> IOEnv (Env TcGblEnv TcLclEnv) Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
where tycon :: TyCon
tycon = FamInst -> TyCon
famInstTyCon FamInst
famInst
fi_ax :: CoAxiom Unbranched
fi_ax = FamInst -> CoAxiom Unbranched
fi_axiom FamInst
famInst
makeInjectivityErrors
:: CoAxiom br
-> CoAxBranch
-> [Bool]
-> [CoAxBranch]
-> [(SDoc, SrcSpan)]
makeInjectivityErrors :: CoAxiom br
-> CoAxBranch -> [Bool] -> [CoAxBranch] -> [(SDoc, SrcSpan)]
makeInjectivityErrors fi_ax :: CoAxiom br
fi_ax axiom :: CoAxBranch
axiom inj :: [Bool]
inj conflicts :: [CoAxBranch]
conflicts
= ASSERT2( any id inj, text "No injective type variables" )
let lhs :: [Type]
lhs = CoAxBranch -> [Type]
coAxBranchLHS CoAxBranch
axiom
rhs :: Type
rhs = CoAxBranch -> Type
coAxBranchRHS CoAxBranch
axiom
fam_tc :: TyCon
fam_tc = CoAxiom br -> TyCon
forall (br :: BranchFlag). CoAxiom br -> TyCon
coAxiomTyCon CoAxiom br
fi_ax
are_conflicts :: Bool
are_conflicts = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [CoAxBranch] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoAxBranch]
conflicts
unused_inj_tvs :: Pair TyCoVarSet
unused_inj_tvs = TyCon -> [Bool] -> [Type] -> Type -> Pair TyCoVarSet
unusedInjTvsInRHS TyCon
fam_tc [Bool]
inj [Type]
lhs Type
rhs
inj_tvs_unused :: Bool
inj_tvs_unused = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Pair Bool -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and (TyCoVarSet -> Bool
isEmptyVarSet (TyCoVarSet -> Bool) -> Pair TyCoVarSet -> Pair Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair TyCoVarSet
unused_inj_tvs)
tf_headed :: Bool
tf_headed = Type -> Bool
isTFHeaded Type
rhs
bare_variables :: [Type]
bare_variables = [Type] -> Type -> [Type]
bareTvInRHSViolated [Type]
lhs Type
rhs
wrong_bare_rhs :: Bool
wrong_bare_rhs = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
bare_variables
err_builder :: SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
err_builder herald :: SDoc
herald eqns :: [CoAxBranch]
eqns
= ( SDoc -> Int -> SDoc -> SDoc
hang SDoc
herald
2 ([SDoc] -> SDoc
vcat ((CoAxBranch -> SDoc) -> [CoAxBranch] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (TyCon -> CoAxBranch -> SDoc
pprCoAxBranchUser TyCon
fam_tc) [CoAxBranch]
eqns))
, CoAxBranch -> SrcSpan
coAxBranchSpan ([CoAxBranch] -> CoAxBranch
forall a. [a] -> a
head [CoAxBranch]
eqns) )
errorIf :: Bool
-> ((SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan))
-> [(SDoc, SrcSpan)]
errorIf p :: Bool
p f :: (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan)
f = if Bool
p then [(SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan)
f SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
err_builder CoAxBranch
axiom] else []
in Bool
-> ((SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan))
-> [(SDoc, SrcSpan)]
errorIf Bool
are_conflicts ([CoAxBranch]
-> (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch
-> (SDoc, SrcSpan)
conflictInjInstErr [CoAxBranch]
conflicts )
[(SDoc, SrcSpan)] -> [(SDoc, SrcSpan)] -> [(SDoc, SrcSpan)]
forall a. [a] -> [a] -> [a]
++ Bool
-> ((SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan))
-> [(SDoc, SrcSpan)]
errorIf Bool
inj_tvs_unused (Pair TyCoVarSet
-> (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch
-> (SDoc, SrcSpan)
unusedInjectiveVarsErr Pair TyCoVarSet
unused_inj_tvs)
[(SDoc, SrcSpan)] -> [(SDoc, SrcSpan)] -> [(SDoc, SrcSpan)]
forall a. [a] -> [a] -> [a]
++ Bool
-> ((SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan))
-> [(SDoc, SrcSpan)]
errorIf Bool
tf_headed (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan)
tfHeadedErr
[(SDoc, SrcSpan)] -> [(SDoc, SrcSpan)] -> [(SDoc, SrcSpan)]
forall a. [a] -> [a] -> [a]
++ Bool
-> ((SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan))
-> [(SDoc, SrcSpan)]
errorIf Bool
wrong_bare_rhs ([Type]
-> (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch
-> (SDoc, SrcSpan)
bareVariableInRHSErr [Type]
bare_variables)
unusedInjTvsInRHS :: TyCon -> [Bool] -> [Type] -> Type -> Pair TyVarSet
unusedInjTvsInRHS :: TyCon -> [Bool] -> [Type] -> Type -> Pair TyCoVarSet
unusedInjTvsInRHS tycon :: TyCon
tycon injList :: [Bool]
injList lhs :: [Type]
lhs rhs :: Type
rhs =
(TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`minusVarSet` TyCoVarSet
injRhsVars) (TyCoVarSet -> TyCoVarSet) -> Pair TyCoVarSet -> Pair TyCoVarSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair TyCoVarSet
injLHSVars
where
inj_pairs :: [(Type, ArgFlag)]
inj_pairs :: [(Type, ArgFlag)]
inj_pairs = ASSERT2( injList `equalLength` lhs
, ppr tycon $$ ppr injList $$ ppr lhs )
[Bool] -> [(Type, ArgFlag)] -> [(Type, ArgFlag)]
forall a. [Bool] -> [a] -> [a]
filterByList [Bool]
injList ([Type]
lhs [Type] -> [ArgFlag] -> [(Type, ArgFlag)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` TyCon -> [Type] -> [ArgFlag]
tyConArgFlags TyCon
tycon [Type]
lhs)
invis_lhs, vis_lhs :: [Type]
(invis_lhs :: [Type]
invis_lhs, vis_lhs :: [Type]
vis_lhs) = [(Type, ArgFlag)] -> ([Type], [Type])
forall a. [(a, ArgFlag)] -> ([a], [a])
partitionInvisibles [(Type, ArgFlag)]
inj_pairs
invis_vars :: TyCoVarSet
invis_vars = [Type] -> TyCoVarSet
tyCoVarsOfTypes [Type]
invis_lhs
Pair invis_vars' :: TyCoVarSet
invis_vars' vis_vars :: TyCoVarSet
vis_vars = [Type] -> Pair TyCoVarSet
splitVisVarsOfTypes [Type]
vis_lhs
injLHSVars :: Pair TyCoVarSet
injLHSVars
= TyCoVarSet -> TyCoVarSet -> Pair TyCoVarSet
forall a. a -> a -> Pair a
Pair (TyCoVarSet
invis_vars TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`minusVarSet` TyCoVarSet
vis_vars TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`unionVarSet` TyCoVarSet
invis_vars')
TyCoVarSet
vis_vars
injRhsVars :: TyCoVarSet
injRhsVars = Type -> TyCoVarSet
injTyVarsOfType Type
rhs
injTyVarsOfType :: TcTauType -> TcTyVarSet
injTyVarsOfType :: Type -> TyCoVarSet
injTyVarsOfType ty :: Type
ty
| Just ty' :: Type
ty' <- Type -> Maybe Type
coreView Type
ty
= Type -> TyCoVarSet
injTyVarsOfType Type
ty'
injTyVarsOfType (TyVarTy v :: TyVar
v)
= TyVar -> TyCoVarSet
unitVarSet TyVar
v TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`unionVarSet` Type -> TyCoVarSet
injTyVarsOfType (TyVar -> Type
tyVarKind TyVar
v)
injTyVarsOfType (TyConApp tc :: TyCon
tc tys :: [Type]
tys)
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
= case TyCon -> Injectivity
tyConInjectivityInfo TyCon
tc of
NotInjective -> TyCoVarSet
emptyVarSet
Injective inj :: [Bool]
inj -> [Type] -> TyCoVarSet
injTyVarsOfTypes ([Bool] -> [Type] -> [Type]
forall a. [Bool] -> [a] -> [a]
filterByList [Bool]
inj [Type]
tys)
| Bool
otherwise
= [Type] -> TyCoVarSet
injTyVarsOfTypes [Type]
tys
injTyVarsOfType (LitTy {})
= TyCoVarSet
emptyVarSet
injTyVarsOfType (FunTy arg :: Type
arg res :: Type
res)
= Type -> TyCoVarSet
injTyVarsOfType Type
arg TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`unionVarSet` Type -> TyCoVarSet
injTyVarsOfType Type
res
injTyVarsOfType (AppTy fun :: Type
fun arg :: Type
arg)
= Type -> TyCoVarSet
injTyVarsOfType Type
fun TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`unionVarSet` Type -> TyCoVarSet
injTyVarsOfType Type
arg
injTyVarsOfType (CastTy ty :: Type
ty _) = Type -> TyCoVarSet
injTyVarsOfType Type
ty
injTyVarsOfType (CoercionTy {}) = TyCoVarSet
emptyVarSet
injTyVarsOfType (ForAllTy {}) =
String -> TyCoVarSet
forall a. String -> a
panic "unusedInjTvsInRHS.injTyVarsOfType"
injTyVarsOfTypes :: [Type] -> VarSet
injTyVarsOfTypes :: [Type] -> TyCoVarSet
injTyVarsOfTypes tys :: [Type]
tys = (Type -> TyCoVarSet) -> [Type] -> TyCoVarSet
forall a. (a -> TyCoVarSet) -> [a] -> TyCoVarSet
mapUnionVarSet Type -> TyCoVarSet
injTyVarsOfType [Type]
tys
isTFHeaded :: Type -> Bool
isTFHeaded :: Type -> Bool
isTFHeaded ty :: Type
ty | Just ty' :: Type
ty' <- Type -> Maybe Type
coreView Type
ty
= Type -> Bool
isTFHeaded Type
ty'
isTFHeaded ty :: Type
ty | (TyConApp tc :: TyCon
tc args :: [Type]
args) <- Type
ty
, TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
= [Type]
args [Type] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthIs` TyCon -> Int
tyConArity TyCon
tc
isTFHeaded _ = Bool
False
bareTvInRHSViolated :: [Type] -> Type -> [Type]
bareTvInRHSViolated :: [Type] -> Type -> [Type]
bareTvInRHSViolated pats :: [Type]
pats rhs :: Type
rhs | Type -> Bool
isTyVarTy Type
rhs
= (Type -> Bool) -> [Type] -> [Type]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Type -> Bool) -> Type -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Bool
isTyVarTy) [Type]
pats
bareTvInRHSViolated _ _ = []
type InjErrorBuilder = SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
injectivityErrorHerald :: Bool -> SDoc
injectivityErrorHerald :: Bool -> SDoc
injectivityErrorHerald isSingular :: Bool
isSingular =
String -> SDoc
text "Type family equation" SDoc -> SDoc -> SDoc
<> Bool -> SDoc
s Bool
isSingular SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "violate" SDoc -> SDoc -> SDoc
<>
Bool -> SDoc
s (Bool -> Bool
not Bool
isSingular) SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "injectivity annotation" SDoc -> SDoc -> SDoc
<>
if Bool
isSingular then SDoc
dot else SDoc
colon
where
s :: Bool -> SDoc
s False = String -> SDoc
text "s"
s True = SDoc
empty
conflictInjInstErr :: [CoAxBranch] -> InjErrorBuilder -> CoAxBranch
-> (SDoc, SrcSpan)
conflictInjInstErr :: [CoAxBranch]
-> (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch
-> (SDoc, SrcSpan)
conflictInjInstErr conflictingEqns :: [CoAxBranch]
conflictingEqns errorBuilder :: SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder tyfamEqn :: CoAxBranch
tyfamEqn
| confEqn :: CoAxBranch
confEqn : _ <- [CoAxBranch]
conflictingEqns
= SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder (Bool -> SDoc
injectivityErrorHerald Bool
False) [CoAxBranch
confEqn, CoAxBranch
tyfamEqn]
| Bool
otherwise
= String -> (SDoc, SrcSpan)
forall a. String -> a
panic "conflictInjInstErr"
unusedInjectiveVarsErr :: Pair TyVarSet -> InjErrorBuilder -> CoAxBranch
-> (SDoc, SrcSpan)
unusedInjectiveVarsErr :: Pair TyCoVarSet
-> (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch
-> (SDoc, SrcSpan)
unusedInjectiveVarsErr (Pair invis_vars :: TyCoVarSet
invis_vars vis_vars :: TyCoVarSet
vis_vars) errorBuilder :: SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder tyfamEqn :: CoAxBranch
tyfamEqn
= let (doc :: SDoc
doc, loc :: SrcSpan
loc) = SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder (Bool -> SDoc
injectivityErrorHerald Bool
True SDoc -> SDoc -> SDoc
$$ SDoc
msg)
[CoAxBranch
tyfamEqn]
in (Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen Bool
has_kinds SDoc
doc, SrcSpan
loc)
where
tvs :: TyCoVarSet
tvs = TyCoVarSet
invis_vars TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`unionVarSet` TyCoVarSet
vis_vars
has_types :: Bool
has_types = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ TyCoVarSet -> Bool
isEmptyVarSet TyCoVarSet
vis_vars
has_kinds :: Bool
has_kinds = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ TyCoVarSet -> Bool
isEmptyVarSet TyCoVarSet
invis_vars
doc :: SDoc
doc = [SDoc] -> SDoc
sep [ SDoc
what SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "variable" SDoc -> SDoc -> SDoc
<>
TyCoVarSet -> SDoc
pluralVarSet TyCoVarSet
tvs SDoc -> SDoc -> SDoc
<+> TyCoVarSet -> ([TyVar] -> SDoc) -> SDoc
pprVarSet TyCoVarSet
tvs ([TyVar] -> SDoc
forall a. Outputable a => [a] -> SDoc
pprQuotedList ([TyVar] -> SDoc) -> ([TyVar] -> [TyVar]) -> [TyVar] -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TyVar] -> [TyVar]
scopedSort)
, String -> SDoc
text "cannot be inferred from the right-hand side." ]
what :: SDoc
what = case (Bool
has_types, Bool
has_kinds) of
(True, True) -> String -> SDoc
text "Type and kind"
(True, False) -> String -> SDoc
text "Type"
(False, True) -> String -> SDoc
text "Kind"
(False, False) -> String -> SDoc -> SDoc
forall a. HasCallStack => String -> SDoc -> a
pprPanic "mkUnusedInjectiveVarsErr" (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ TyCoVarSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCoVarSet
tvs
msg :: SDoc
msg = SDoc
doc SDoc -> SDoc -> SDoc
$$ String -> SDoc
text "In the type family equation:"
tfHeadedErr :: InjErrorBuilder -> CoAxBranch
-> (SDoc, SrcSpan)
tfHeadedErr :: (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch -> (SDoc, SrcSpan)
tfHeadedErr errorBuilder :: SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder famInst :: CoAxBranch
famInst
= SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder (Bool -> SDoc
injectivityErrorHerald Bool
True SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "RHS of injective type family equation cannot" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "be a type family:") [CoAxBranch
famInst]
bareVariableInRHSErr :: [Type] -> InjErrorBuilder -> CoAxBranch
-> (SDoc, SrcSpan)
bareVariableInRHSErr :: [Type]
-> (SDoc -> [CoAxBranch] -> (SDoc, SrcSpan))
-> CoAxBranch
-> (SDoc, SrcSpan)
bareVariableInRHSErr tys :: [Type]
tys errorBuilder :: SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder famInst :: CoAxBranch
famInst
= SDoc -> [CoAxBranch] -> (SDoc, SrcSpan)
errorBuilder (Bool -> SDoc
injectivityErrorHerald Bool
True SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "RHS of injective type family equation is a bare" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "type variable" SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "but these LHS type and kind patterns are not bare" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "variables:" SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => [a] -> SDoc
pprQuotedList [Type]
tys) [CoAxBranch
famInst]
reportConflictInstErr :: FamInst -> [FamInstMatch] -> TcRn ()
reportConflictInstErr :: FamInst -> [FamInstMatch] -> TcRn ()
reportConflictInstErr _ []
= () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
reportConflictInstErr fam_inst :: FamInst
fam_inst (match1 :: FamInstMatch
match1 : _)
| FamInstMatch { fim_instance :: FamInstMatch -> FamInst
fim_instance = FamInst
conf_inst } <- FamInstMatch
match1
, let sorted :: [FamInst]
sorted = (FamInst -> SrcLoc) -> [FamInst] -> [FamInst]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortWith FamInst -> SrcLoc
getSpan [FamInst
fam_inst, FamInst
conf_inst]
fi1 :: FamInst
fi1 = [FamInst] -> FamInst
forall a. [a] -> a
head [FamInst]
sorted
span :: SrcSpan
span = CoAxBranch -> SrcSpan
coAxBranchSpan (CoAxiom Unbranched -> CoAxBranch
coAxiomSingleBranch (FamInst -> CoAxiom Unbranched
famInstAxiom FamInst
fi1))
= SrcSpan -> TcRn () -> TcRn ()
forall a. SrcSpan -> TcRn a -> TcRn a
setSrcSpan SrcSpan
span (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$ SDoc -> TcRn ()
addErr (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Conflicting family instance declarations:")
2 ([SDoc] -> SDoc
vcat [ TyCon -> CoAxBranch -> SDoc
pprCoAxBranchUser (CoAxiom Unbranched -> TyCon
forall (br :: BranchFlag). CoAxiom br -> TyCon
coAxiomTyCon CoAxiom Unbranched
ax) (CoAxiom Unbranched -> CoAxBranch
coAxiomSingleBranch CoAxiom Unbranched
ax)
| FamInst
fi <- [FamInst]
sorted
, let ax :: CoAxiom Unbranched
ax = FamInst -> CoAxiom Unbranched
famInstAxiom FamInst
fi ])
where
getSpan :: FamInst -> SrcLoc
getSpan = CoAxiom Unbranched -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc (CoAxiom Unbranched -> SrcLoc)
-> (FamInst -> CoAxiom Unbranched) -> FamInst -> SrcLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FamInst -> CoAxiom Unbranched
famInstAxiom
tcGetFamInstEnvs :: TcM FamInstEnvs
tcGetFamInstEnvs :: TcM (FamInstEnv, FamInstEnv)
tcGetFamInstEnvs
= do { ExternalPackageState
eps <- TcRnIf TcGblEnv TcLclEnv ExternalPackageState
forall gbl lcl. TcRnIf gbl lcl ExternalPackageState
getEps; TcGblEnv
env <- TcRnIf TcGblEnv TcLclEnv TcGblEnv
forall gbl lcl. TcRnIf gbl lcl gbl
getGblEnv
; (FamInstEnv, FamInstEnv) -> TcM (FamInstEnv, FamInstEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (ExternalPackageState -> FamInstEnv
eps_fam_inst_env ExternalPackageState
eps, TcGblEnv -> FamInstEnv
tcg_fam_inst_env TcGblEnv
env) }