{-# LANGUAGE CPP, GADTs, ViewPatterns #-}
module FamInst (
FamInstEnvs, tcGetFamInstEnvs,
checkFamInstConsistency, tcExtendLocalFamInstEnv,
tcLookupDataFamInst, tcLookupDataFamInst_maybe,
tcInstNewTyCon_maybe, tcTopNormaliseNewTypeTF_maybe,
newFamInst,
reportInjectivityErrors, reportConflictingInjectivityErrs
) 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 TyCoRep
import TyCoFVs
import TyCoPpr ( pprWithExplicitKindsWhen )
import TcMType
import Name
import Panic
import VarSet
import FV
import Bag( Bag, unionBags, unitBag )
import Control.Monad
import Data.List.NonEmpty ( NonEmpty(..) )
import qualified GHC.LanguageExtensions as LangExt
#include "HsVersions.h"
newFamInst :: FamFlavor -> CoAxiom Unbranched -> TcM FamInst
newFamInst :: FamFlavor -> CoAxiom Unbranched -> TcM FamInst
newFamInst 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( lhs_kind `eqType` rhs_kind, text "kind" <+> pp_ax $$ ppr lhs_kind $$ ppr rhs_kind )
do { (TCvSubst
subst, [TyVar]
tvs') <- [TyVar] -> TcM (TCvSubst, [TyVar])
freshenTyVarBndrs [TyVar]
tvs
; (TCvSubst
subst, [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
Maybe SDoc
Nothing -> () -> TcRn ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just SDoc
fail_msg -> String -> SDoc -> TcRn ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"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 [Module]
directlyImpMods
= do { (ExternalPackageState
eps, HomePackageTable
hpt) <- TcRnIf TcGblEnv TcLclEnv (ExternalPackageState, HomePackageTable)
forall gbl lcl.
TcRnIf gbl lcl (ExternalPackageState, HomePackageTable)
getEpsAndHpt
; String -> SDoc -> TcRn ()
traceTc String
"checkFamInstConsistency" ([Module] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Module]
directlyImpMods)
; let {
modIface :: Module -> ModIface
modIface Module
mod =
case HomePackageTable -> PackageIfaceTable -> Module -> Maybe ModIface
lookupIfaceByModule HomePackageTable
hpt (ExternalPackageState -> PackageIfaceTable
eps_PIT ExternalPackageState
eps) Module
mod of
Maybe ModIface
Nothing -> String -> SDoc -> ModIface
forall a. String -> SDoc -> a
panicDoc String
"FamInst.checkFamInstConsistency"
(Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod SDoc -> SDoc -> SDoc
$$ HomePackageTable -> SDoc
pprHPT HomePackageTable
hpt)
Just ModIface
iface -> ModIface
iface
; modConsistent :: Module -> [Module]
; modConsistent :: Module -> [Module]
modConsistent Module
mod =
if ModIfaceBackend -> Bool
mi_finsts (ModIface -> IfaceBackendExts 'ModIfaceFinal
forall (phase :: ModIfacePhase).
ModIface_ phase -> IfaceBackendExts phase
mi_final_exts (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
forall (phase :: ModIfacePhase). ModIface_ phase -> 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
forall (phase :: ModIfacePhase). ModIface_ phase -> 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 ModuleEnv FamInstEnv
hpt_fam_insts Module -> [Module]
modConsistent [Module]
mods = [Module] -> ModuleSet -> [Module] -> TcRn ()
go [] ModuleSet
emptyModuleSet [Module]
mods
where
go :: [Module]
-> ModuleSet
-> [Module]
-> TcM ()
go :: [Module] -> ModuleSet -> [Module] -> TcRn ()
go [Module]
_ ModuleSet
_ [] = () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
go [Module]
consistent ModuleSet
consistent_set (Module
mod:[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 ModuleEnv FamInstEnv
hpt_fam_insts Module
m1 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'
(FamInstEnv
env1, 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 -> TcRn ()) -> [FamInst] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((FamInstEnv, FamInstEnv) -> FamInst -> TcRn ()
checkForConflicts (FamInstEnv
emptyFamInstEnv, FamInstEnv
env2)) [FamInst]
check_now
; (FamInst -> TcRn ()) -> [FamInst] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((FamInstEnv, FamInstEnv) -> FamInst -> TcRn ()
checkForInjectivityConflicts (FamInstEnv
emptyFamInstEnv,FamInstEnv
env2)) [FamInst]
check_now
}
getFamInsts :: ModuleEnv FamInstEnv -> Module -> TcM FamInstEnv
getFamInsts :: ModuleEnv FamInstEnv -> Module -> TcM FamInstEnv
getFamInsts ModuleEnv FamInstEnv
hpt_fam_insts Module
mod
| Just 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 String
"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 String
"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 (FamInstEnv, FamInstEnv)
fam_inst_envs TyCon
tc [Type]
tc_args
| Just (TyCon
rep_tc, [Type]
rep_args, 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 (FamInstEnv, FamInstEnv)
fam_inst_envs TyCon
tc [Type]
tc_args
| TyCon -> Bool
isDataFamilyTyCon TyCon
tc
, FamInstMatch
match : [FamInstMatch]
_ <- (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 (FamInstEnv, FamInstEnv)
faminsts GlobalRdrEnv
rdr_env 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 (Bag GlobalRdrElt
gres1, TcCoercion
co1) (Bag GlobalRdrElt
gres2, 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 RecTcChecker
rec_nts TyCon
tc [Type]
tys
| Just (TyCon
tc', [Type]
tys', 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 (\(Bag GlobalRdrElt
gres, 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 RecTcChecker
rec_nts TyCon
tc [Type]
tys
| Just DataCon
con <- TyCon -> Maybe DataCon
newTyConDataCon_maybe TyCon
tc
, Just 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 (\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 [] TcM a
thing_inside = TcM a
thing_inside
tcExtendLocalFamInstEnv [FamInst]
fam_insts 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
; (FamInstEnv
inst_env', [FamInst]
fam_insts') <- ((FamInstEnv, [FamInst])
-> FamInst
-> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst]))
-> (FamInstEnv, [FamInst])
-> [FamInst]
-> IOEnv (Env TcGblEnv TcLclEnv) (FamInstEnv, [FamInst])
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
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 [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 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 String
"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 (FamInstEnv
home_fie, [FamInst]
my_fis) FamInst
fam_inst
= do { String -> SDoc -> TcRn ()
traceTc String
"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 String
"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_errs) <- TcRn () -> TcRn ((), Bool)
forall a. TcRn a -> TcRn (a, Bool)
askNoErrs (TcRn () -> TcRn ((), Bool)) -> TcRn () -> TcRn ((), Bool)
forall a b. (a -> b) -> a -> b
$
do { (FamInstEnv, FamInstEnv) -> FamInst -> TcRn ()
checkForConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
; (FamInstEnv, FamInstEnv) -> FamInst -> TcRn ()
checkForInjectivityConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
; FamInst -> TcRn ()
checkInjectiveEquation FamInst
fam_inst
}
; if Bool
no_errs 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 ()
checkForConflicts :: (FamInstEnv, FamInstEnv) -> FamInst -> TcRn ()
checkForConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
= do { let conflicts :: [FamInstMatch]
conflicts = (FamInstEnv, FamInstEnv) -> FamInst -> [FamInstMatch]
lookupFamInstEnvConflicts (FamInstEnv, FamInstEnv)
inst_envs FamInst
fam_inst
; String -> SDoc -> TcRn ()
traceTc String
"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 }
checkForInjectivityConflicts :: FamInstEnvs -> FamInst -> TcM ()
checkForInjectivityConflicts :: (FamInstEnv, FamInstEnv) -> FamInst -> TcRn ()
checkForInjectivityConflicts (FamInstEnv, FamInstEnv)
instEnvs FamInst
famInst
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tycon
, Injective [Bool]
inj <- TyCon -> Injectivity
tyConInjectivityInfo TyCon
tycon
= let conflicts :: [CoAxBranch]
conflicts = [Bool] -> (FamInstEnv, FamInstEnv) -> FamInst -> [CoAxBranch]
lookupFamInstEnvInjectivityConflicts [Bool]
inj (FamInstEnv, FamInstEnv)
instEnvs FamInst
famInst in
TyCon -> [CoAxBranch] -> CoAxBranch -> TcRn ()
reportConflictingInjectivityErrs TyCon
tycon [CoAxBranch]
conflicts (CoAxiom Unbranched -> CoAxBranch
coAxiomSingleBranch (FamInst -> CoAxiom Unbranched
fi_axiom FamInst
famInst))
| Bool
otherwise
= () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where tycon :: TyCon
tycon = FamInst -> TyCon
famInstTyCon FamInst
famInst
checkInjectiveEquation :: FamInst -> TcM ()
checkInjectiveEquation :: FamInst -> TcRn ()
checkInjectiveEquation FamInst
famInst
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tycon
, Injective [Bool]
inj <- TyCon -> Injectivity
tyConInjectivityInfo TyCon
tycon = do
{ DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let axiom :: CoAxBranch
axiom = CoAxiom Unbranched -> CoAxBranch
coAxiomSingleBranch CoAxiom Unbranched
fi_ax
; DynFlags -> CoAxiom Unbranched -> CoAxBranch -> [Bool] -> TcRn ()
forall (br :: BranchFlag).
DynFlags -> CoAxiom br -> CoAxBranch -> [Bool] -> TcRn ()
reportInjectivityErrors DynFlags
dflags CoAxiom Unbranched
fi_ax CoAxBranch
axiom [Bool]
inj
}
| Bool
otherwise
= () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where tycon :: TyCon
tycon = FamInst -> TyCon
famInstTyCon FamInst
famInst
fi_ax :: CoAxiom Unbranched
fi_ax = FamInst -> CoAxiom Unbranched
fi_axiom FamInst
famInst
reportInjectivityErrors
:: DynFlags
-> CoAxiom br
-> CoAxBranch
-> [Bool]
-> TcM ()
reportInjectivityErrors :: DynFlags -> CoAxiom br -> CoAxBranch -> [Bool] -> TcRn ()
reportInjectivityErrors DynFlags
dflags CoAxiom br
fi_ax CoAxBranch
axiom [Bool]
inj
= ASSERT2( any id inj, text "No injective type variables" )
do 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
(TyCoVarSet
unused_inj_tvs, Bool
unused_vis, Bool
undec_inst_flag)
= DynFlags -> TyCon -> [Type] -> Type -> (TyCoVarSet, Bool, Bool)
unusedInjTvsInRHS DynFlags
dflags TyCon
fam_tc [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
$ TyCoVarSet -> Bool
isEmptyVarSet 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
Bool -> TcRn () -> TcRn ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
inj_tvs_unused (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$ TyCon -> TyCoVarSet -> Bool -> Bool -> CoAxBranch -> TcRn ()
reportUnusedInjectiveVarsErr TyCon
fam_tc TyCoVarSet
unused_inj_tvs
Bool
unused_vis Bool
undec_inst_flag CoAxBranch
axiom
Bool -> TcRn () -> TcRn ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
tf_headed (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$ TyCon -> CoAxBranch -> TcRn ()
reportTfHeadedErr TyCon
fam_tc CoAxBranch
axiom
Bool -> TcRn () -> TcRn ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
wrong_bare_rhs (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$ TyCon -> [Type] -> CoAxBranch -> TcRn ()
reportBareVariableInRHSErr TyCon
fam_tc [Type]
bare_variables CoAxBranch
axiom
isTFHeaded :: Type -> Bool
isTFHeaded :: Type -> Bool
isTFHeaded Type
ty | Just Type
ty' <- Type -> Maybe Type
coreView Type
ty
= Type -> Bool
isTFHeaded Type
ty'
isTFHeaded Type
ty | (TyConApp TyCon
tc [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 Type
_ = Bool
False
bareTvInRHSViolated :: [Type] -> Type -> [Type]
bareTvInRHSViolated :: [Type] -> Type -> [Type]
bareTvInRHSViolated [Type]
pats 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]
_ Type
_ = []
unusedInjTvsInRHS :: DynFlags
-> TyCon
-> [Type]
-> Type
-> ( TyVarSet
, Bool
, Bool )
unusedInjTvsInRHS :: DynFlags -> TyCon -> [Type] -> Type -> (TyCoVarSet, Bool, Bool)
unusedInjTvsInRHS DynFlags
dflags tycon :: TyCon
tycon@(TyCon -> Injectivity
tyConInjectivityInfo -> Injective [Bool]
inj_list) [Type]
lhs Type
rhs =
(TyCoVarSet
bad_vars, Bool
any_invisible, Bool
suggest_undec)
where
undec_inst :: Bool
undec_inst = Extension -> DynFlags -> Bool
xopt Extension
LangExt.UndecidableInstances DynFlags
dflags
inj_lhs :: [Type]
inj_lhs = [Bool] -> [Type] -> [Type]
forall a. [Bool] -> [a] -> [a]
filterByList [Bool]
inj_list [Type]
lhs
lhs_vars :: TyCoVarSet
lhs_vars = [Type] -> TyCoVarSet
tyCoVarsOfTypes [Type]
inj_lhs
rhs_inj_vars :: TyCoVarSet
rhs_inj_vars = FV -> TyCoVarSet
fvVarSet (FV -> TyCoVarSet) -> FV -> TyCoVarSet
forall a b. (a -> b) -> a -> b
$ Bool -> Type -> FV
injectiveVarsOfType Bool
undec_inst Type
rhs
bad_vars :: TyCoVarSet
bad_vars = TyCoVarSet
lhs_vars TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`minusVarSet` TyCoVarSet
rhs_inj_vars
any_bad :: Bool
any_bad = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ TyCoVarSet -> Bool
isEmptyVarSet TyCoVarSet
bad_vars
invis_vars :: TyCoVarSet
invis_vars = FV -> TyCoVarSet
fvVarSet (FV -> TyCoVarSet) -> FV -> TyCoVarSet
forall a b. (a -> b) -> a -> b
$ [Type] -> FV
invisibleVarsOfTypes [TyCon -> [Type] -> Type
mkTyConApp TyCon
tycon [Type]
lhs, Type
rhs]
any_invisible :: Bool
any_invisible = Bool
any_bad Bool -> Bool -> Bool
&& (TyCoVarSet
bad_vars TyCoVarSet -> TyCoVarSet -> Bool
`intersectsVarSet` TyCoVarSet
invis_vars)
suggest_undec :: Bool
suggest_undec = Bool
any_bad Bool -> Bool -> Bool
&&
Bool -> Bool
not Bool
undec_inst Bool -> Bool -> Bool
&&
(TyCoVarSet
lhs_vars TyCoVarSet -> TyCoVarSet -> Bool
`subVarSet` FV -> TyCoVarSet
fvVarSet (Bool -> Type -> FV
injectiveVarsOfType Bool
True Type
rhs))
unusedInjTvsInRHS DynFlags
_ TyCon
_ [Type]
_ Type
_ = (TyCoVarSet
emptyVarSet, Bool
False, Bool
False)
reportConflictingInjectivityErrs :: TyCon -> [CoAxBranch] -> CoAxBranch -> TcM ()
reportConflictingInjectivityErrs :: TyCon -> [CoAxBranch] -> CoAxBranch -> TcRn ()
reportConflictingInjectivityErrs TyCon
_ [] CoAxBranch
_ = () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
reportConflictingInjectivityErrs TyCon
fam_tc (CoAxBranch
confEqn1:[CoAxBranch]
_) CoAxBranch
tyfamEqn
= [(SrcSpan, SDoc)] -> TcRn ()
addErrs [TyCon -> SDoc -> NonEmpty CoAxBranch -> (SrcSpan, SDoc)
buildInjectivityError TyCon
fam_tc SDoc
herald (CoAxBranch
confEqn1 CoAxBranch -> [CoAxBranch] -> NonEmpty CoAxBranch
forall a. a -> [a] -> NonEmpty a
:| [CoAxBranch
tyfamEqn])]
where
herald :: SDoc
herald = String -> SDoc
text String
"Type family equation right-hand sides overlap; this violates" SDoc -> SDoc -> SDoc
$$
String -> SDoc
text String
"the family's injectivity annotation:"
injectivityErrorHerald :: SDoc
injectivityErrorHerald :: SDoc
injectivityErrorHerald =
String -> SDoc
text String
"Type family equation violates the family's injectivity annotation."
reportUnusedInjectiveVarsErr :: TyCon
-> TyVarSet
-> Bool
-> Bool
-> CoAxBranch
-> TcM ()
reportUnusedInjectiveVarsErr :: TyCon -> TyCoVarSet -> Bool -> Bool -> CoAxBranch -> TcRn ()
reportUnusedInjectiveVarsErr TyCon
fam_tc TyCoVarSet
tvs Bool
has_kinds Bool
undec_inst CoAxBranch
tyfamEqn
= let (SrcSpan
loc, SDoc
doc) = TyCon -> SDoc -> NonEmpty CoAxBranch -> (SrcSpan, SDoc)
buildInjectivityError TyCon
fam_tc
(SDoc
injectivityErrorHerald SDoc -> SDoc -> SDoc
$$
SDoc
herald SDoc -> SDoc -> SDoc
$$
String -> SDoc
text String
"In the type family equation:")
(CoAxBranch
tyfamEqn CoAxBranch -> [CoAxBranch] -> NonEmpty CoAxBranch
forall a. a -> [a] -> NonEmpty a
:| [])
in SrcSpan -> SDoc -> TcRn ()
addErrAt SrcSpan
loc (Bool -> SDoc -> SDoc
pprWithExplicitKindsWhen Bool
has_kinds SDoc
doc)
where
herald :: SDoc
herald = [SDoc] -> SDoc
sep [ SDoc
what SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"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 String
"cannot be inferred from the right-hand side." ]
SDoc -> SDoc -> SDoc
$$ SDoc
extra
what :: SDoc
what | Bool
has_kinds = String -> SDoc
text String
"Type/kind"
| Bool
otherwise = String -> SDoc
text String
"Type"
extra :: SDoc
extra | Bool
undec_inst = String -> SDoc
text String
"Using UndecidableInstances might help"
| Bool
otherwise = SDoc
empty
reportTfHeadedErr :: TyCon -> CoAxBranch -> TcM ()
reportTfHeadedErr :: TyCon -> CoAxBranch -> TcRn ()
reportTfHeadedErr TyCon
fam_tc CoAxBranch
branch
= [(SrcSpan, SDoc)] -> TcRn ()
addErrs [TyCon -> SDoc -> NonEmpty CoAxBranch -> (SrcSpan, SDoc)
buildInjectivityError TyCon
fam_tc
(SDoc
injectivityErrorHerald SDoc -> SDoc -> SDoc
$$
String -> SDoc
text String
"RHS of injective type family equation cannot" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text String
"be a type family:")
(CoAxBranch
branch CoAxBranch -> [CoAxBranch] -> NonEmpty CoAxBranch
forall a. a -> [a] -> NonEmpty a
:| [])]
reportBareVariableInRHSErr :: TyCon -> [Type] -> CoAxBranch -> TcM ()
reportBareVariableInRHSErr :: TyCon -> [Type] -> CoAxBranch -> TcRn ()
reportBareVariableInRHSErr TyCon
fam_tc [Type]
tys CoAxBranch
branch
= [(SrcSpan, SDoc)] -> TcRn ()
addErrs [TyCon -> SDoc -> NonEmpty CoAxBranch -> (SrcSpan, SDoc)
buildInjectivityError TyCon
fam_tc
(SDoc
injectivityErrorHerald SDoc -> SDoc -> SDoc
$$
String -> SDoc
text String
"RHS of injective type family equation is a bare" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text String
"type variable" SDoc -> SDoc -> SDoc
$$
String -> SDoc
text String
"but these LHS type and kind patterns are not bare" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text String
"variables:" SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => [a] -> SDoc
pprQuotedList [Type]
tys)
(CoAxBranch
branch CoAxBranch -> [CoAxBranch] -> NonEmpty CoAxBranch
forall a. a -> [a] -> NonEmpty a
:| [])]
buildInjectivityError :: TyCon -> SDoc -> NonEmpty CoAxBranch -> (SrcSpan, SDoc)
buildInjectivityError :: TyCon -> SDoc -> NonEmpty CoAxBranch -> (SrcSpan, SDoc)
buildInjectivityError TyCon
fam_tc SDoc
herald (CoAxBranch
eqn1 :| [CoAxBranch]
rest_eqns)
= ( CoAxBranch -> SrcSpan
coAxBranchSpan CoAxBranch
eqn1
, SDoc -> Int -> SDoc -> SDoc
hang SDoc
herald
Int
2 ([SDoc] -> SDoc
vcat ((CoAxBranch -> SDoc) -> [CoAxBranch] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (TyCon -> CoAxBranch -> SDoc
pprCoAxBranchUser TyCon
fam_tc) (CoAxBranch
eqn1 CoAxBranch -> [CoAxBranch] -> [CoAxBranch]
forall a. a -> [a] -> [a]
: [CoAxBranch]
rest_eqns))) )
reportConflictInstErr :: FamInst -> [FamInstMatch] -> TcRn ()
reportConflictInstErr :: FamInst -> [FamInstMatch] -> TcRn ()
reportConflictInstErr FamInst
_ []
= () -> TcRn ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
reportConflictInstErr FamInst
fam_inst (FamInstMatch
match1 : [FamInstMatch]
_)
| 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 String
"Conflicting family instance declarations:")
Int
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) }