{-# 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) }