{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TypeFamilies #-}
module TcRules ( tcRules ) where
import GhcPrelude
import GHC.Hs
import TcRnTypes
import TcRnMonad
import TcSimplify
import Constraint
import Predicate
import TcOrigin
import TcMType
import TcType
import TcHsType
import TcExpr
import TcEnv
import TcUnify( buildImplicationFor )
import TcEvidence( mkTcCoVarCo )
import Type
import TyCon( isTypeFamilyTyCon )
import Id
import Var( EvVar )
import VarSet
import BasicTypes ( RuleName )
import SrcLoc
import Outputable
import FastString
import Bag
tcRules :: [LRuleDecls GhcRn] -> TcM [LRuleDecls GhcTcId]
tcRules :: [LRuleDecls GhcRn] -> TcM [LRuleDecls GhcTcId]
tcRules [LRuleDecls GhcRn]
decls = (LRuleDecls GhcRn
-> IOEnv (Env TcGblEnv TcLclEnv) (LRuleDecls GhcTcId))
-> [LRuleDecls GhcRn] -> TcM [LRuleDecls GhcTcId]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((SrcSpanLess (LRuleDecls GhcRn)
-> TcM (SrcSpanLess (LRuleDecls GhcTcId)))
-> LRuleDecls GhcRn
-> IOEnv (Env TcGblEnv TcLclEnv) (LRuleDecls GhcTcId)
forall a b.
(HasSrcSpan a, HasSrcSpan b) =>
(SrcSpanLess a -> TcM (SrcSpanLess b)) -> a -> TcM b
wrapLocM SrcSpanLess (LRuleDecls GhcRn)
-> TcM (SrcSpanLess (LRuleDecls GhcTcId))
RuleDecls GhcRn -> TcM (RuleDecls GhcTcId)
tcRuleDecls) [LRuleDecls GhcRn]
decls
tcRuleDecls :: RuleDecls GhcRn -> TcM (RuleDecls GhcTcId)
tcRuleDecls :: RuleDecls GhcRn -> TcM (RuleDecls GhcTcId)
tcRuleDecls (HsRules { rds_src :: forall pass. RuleDecls pass -> SourceText
rds_src = SourceText
src
, rds_rules :: forall pass. RuleDecls pass -> [LRuleDecl pass]
rds_rules = [LRuleDecl GhcRn]
decls })
= do { [LRuleDecl GhcTcId]
tc_decls <- (LRuleDecl GhcRn
-> IOEnv (Env TcGblEnv TcLclEnv) (LRuleDecl GhcTcId))
-> [LRuleDecl GhcRn]
-> IOEnv (Env TcGblEnv TcLclEnv) [LRuleDecl GhcTcId]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((SrcSpanLess (LRuleDecl GhcRn)
-> TcM (SrcSpanLess (LRuleDecl GhcTcId)))
-> LRuleDecl GhcRn
-> IOEnv (Env TcGblEnv TcLclEnv) (LRuleDecl GhcTcId)
forall a b.
(HasSrcSpan a, HasSrcSpan b) =>
(SrcSpanLess a -> TcM (SrcSpanLess b)) -> a -> TcM b
wrapLocM SrcSpanLess (LRuleDecl GhcRn)
-> TcM (SrcSpanLess (LRuleDecl GhcTcId))
RuleDecl GhcRn -> TcM (RuleDecl GhcTcId)
tcRule) [LRuleDecl GhcRn]
decls
; RuleDecls GhcTcId -> TcM (RuleDecls GhcTcId)
forall (m :: * -> *) a. Monad m => a -> m a
return (RuleDecls GhcTcId -> TcM (RuleDecls GhcTcId))
-> RuleDecls GhcTcId -> TcM (RuleDecls GhcTcId)
forall a b. (a -> b) -> a -> b
$ HsRules :: forall pass.
XCRuleDecls pass
-> SourceText -> [LRuleDecl pass] -> RuleDecls pass
HsRules { rds_ext :: XCRuleDecls GhcTcId
rds_ext = XCRuleDecls GhcTcId
NoExtField
noExtField
, rds_src :: SourceText
rds_src = SourceText
src
, rds_rules :: [LRuleDecl GhcTcId]
rds_rules = [LRuleDecl GhcTcId]
tc_decls } }
tcRuleDecls (XRuleDecls XXRuleDecls GhcRn
nec) = NoExtCon -> TcM (RuleDecls GhcTcId)
forall a. NoExtCon -> a
noExtCon XXRuleDecls GhcRn
NoExtCon
nec
tcRule :: RuleDecl GhcRn -> TcM (RuleDecl GhcTcId)
tcRule :: RuleDecl GhcRn -> TcM (RuleDecl GhcTcId)
tcRule (HsRule { rd_ext :: forall pass. RuleDecl pass -> XHsRule pass
rd_ext = XHsRule GhcRn
ext
, rd_name :: forall pass. RuleDecl pass -> Located (SourceText, RuleName)
rd_name = rname :: Located (SourceText, RuleName)
rname@(L SrcSpan
_ (SourceText
_,RuleName
name))
, rd_act :: forall pass. RuleDecl pass -> Activation
rd_act = Activation
act
, rd_tyvs :: forall pass. RuleDecl pass -> Maybe [LHsTyVarBndr (NoGhcTc pass)]
rd_tyvs = Maybe [LHsTyVarBndr (NoGhcTc GhcRn)]
ty_bndrs
, rd_tmvs :: forall pass. RuleDecl pass -> [LRuleBndr pass]
rd_tmvs = [LRuleBndr GhcRn]
tm_bndrs
, rd_lhs :: forall pass. RuleDecl pass -> Located (HsExpr pass)
rd_lhs = Located (HsExpr GhcRn)
lhs
, rd_rhs :: forall pass. RuleDecl pass -> Located (HsExpr pass)
rd_rhs = Located (HsExpr GhcRn)
rhs })
= MsgDoc -> TcM (RuleDecl GhcTcId) -> TcM (RuleDecl GhcTcId)
forall a. MsgDoc -> TcM a -> TcM a
addErrCtxt (RuleName -> MsgDoc
ruleCtxt RuleName
name) (TcM (RuleDecl GhcTcId) -> TcM (RuleDecl GhcTcId))
-> TcM (RuleDecl GhcTcId) -> TcM (RuleDecl GhcTcId)
forall a b. (a -> b) -> a -> b
$
do { String -> MsgDoc -> TcRn ()
traceTc String
"---- Rule ------" (Located (SourceText, RuleName) -> MsgDoc
pprFullRuleName Located (SourceText, RuleName)
rname)
; (TcLevel
tc_lvl, ([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
stuff) <- TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
(TcLevel,
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType))
forall a. TcM a -> TcM (TcLevel, a)
pushTcLevelM (TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
(TcLevel,
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)))
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
(TcLevel,
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType))
forall a b. (a -> b) -> a -> b
$
Maybe [LHsTyVarBndr GhcRn]
-> [LRuleBndr GhcRn]
-> Located (HsExpr GhcRn)
-> Located (HsExpr GhcRn)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
generateRuleConstraints Maybe [LHsTyVarBndr (NoGhcTc GhcRn)]
Maybe [LHsTyVarBndr GhcRn]
ty_bndrs [LRuleBndr GhcRn]
tm_bndrs Located (HsExpr GhcRn)
lhs Located (HsExpr GhcRn)
rhs
; let ([TyVar]
tv_bndrs, [TyVar]
id_bndrs, LHsExpr GhcTcId
lhs', WantedConstraints
lhs_wanted
, LHsExpr GhcTcId
rhs', WantedConstraints
rhs_wanted, TcType
rule_ty) = ([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
stuff
; String -> MsgDoc -> TcRn ()
traceTc String
"tcRule 1" ([MsgDoc] -> MsgDoc
vcat [ Located (SourceText, RuleName) -> MsgDoc
pprFullRuleName Located (SourceText, RuleName)
rname
, WantedConstraints -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr WantedConstraints
lhs_wanted
, WantedConstraints -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr WantedConstraints
rhs_wanted ])
; ([TyVar]
lhs_evs, WantedConstraints
residual_lhs_wanted)
<- RuleName
-> TcLevel
-> WantedConstraints
-> WantedConstraints
-> TcM ([TyVar], WantedConstraints)
simplifyRule RuleName
name TcLevel
tc_lvl WantedConstraints
lhs_wanted WantedConstraints
rhs_wanted
; let tpl_ids :: [TyVar]
tpl_ids = [TyVar]
lhs_evs [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
id_bndrs
; CandidatesQTvs
forall_tkvs <- [TcType] -> TcM CandidatesQTvs
candidateQTyVarsOfTypes ([TcType] -> TcM CandidatesQTvs) -> [TcType] -> TcM CandidatesQTvs
forall a b. (a -> b) -> a -> b
$
(TcType -> TcType) -> [TcType] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map ([TyVar] -> TcType -> TcType
mkSpecForAllTys [TyVar]
tv_bndrs) ([TcType] -> [TcType]) -> [TcType] -> [TcType]
forall a b. (a -> b) -> a -> b
$
TcType
rule_ty TcType -> [TcType] -> [TcType]
forall a. a -> [a] -> [a]
: (TyVar -> TcType) -> [TyVar] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map TyVar -> TcType
idType [TyVar]
tpl_ids
; [TyVar]
qtkvs <- CandidatesQTvs -> TcM [TyVar]
quantifyTyVars CandidatesQTvs
forall_tkvs
; String -> MsgDoc -> TcRn ()
traceTc String
"tcRule" ([MsgDoc] -> MsgDoc
vcat [ Located (SourceText, RuleName) -> MsgDoc
pprFullRuleName Located (SourceText, RuleName)
rname
, CandidatesQTvs -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr CandidatesQTvs
forall_tkvs
, [TyVar] -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr [TyVar]
qtkvs
, [TyVar] -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr [TyVar]
tv_bndrs
, TcType -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr TcType
rule_ty
, [MsgDoc] -> MsgDoc
vcat [ TyVar -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr TyVar
id MsgDoc -> MsgDoc -> MsgDoc
<+> MsgDoc
dcolon MsgDoc -> MsgDoc -> MsgDoc
<+> TcType -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr (TyVar -> TcType
idType TyVar
id) | TyVar
id <- [TyVar]
tpl_ids ]
])
; let all_qtkvs :: [TyVar]
all_qtkvs = [TyVar]
qtkvs [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
tv_bndrs
skol_info :: SkolemInfo
skol_info = RuleName -> SkolemInfo
RuleSkol RuleName
name
; (Bag Implication
lhs_implic, TcEvBinds
lhs_binds) <- TcLevel
-> SkolemInfo
-> [TyVar]
-> [TyVar]
-> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor TcLevel
tc_lvl SkolemInfo
skol_info [TyVar]
all_qtkvs
[TyVar]
lhs_evs WantedConstraints
residual_lhs_wanted
; (Bag Implication
rhs_implic, TcEvBinds
rhs_binds) <- TcLevel
-> SkolemInfo
-> [TyVar]
-> [TyVar]
-> WantedConstraints
-> TcM (Bag Implication, TcEvBinds)
buildImplicationFor TcLevel
tc_lvl SkolemInfo
skol_info [TyVar]
all_qtkvs
[TyVar]
lhs_evs WantedConstraints
rhs_wanted
; Bag Implication -> TcRn ()
emitImplications (Bag Implication
lhs_implic Bag Implication -> Bag Implication -> Bag Implication
forall a. Bag a -> Bag a -> Bag a
`unionBags` Bag Implication
rhs_implic)
; RuleDecl GhcTcId -> TcM (RuleDecl GhcTcId)
forall (m :: * -> *) a. Monad m => a -> m a
return (RuleDecl GhcTcId -> TcM (RuleDecl GhcTcId))
-> RuleDecl GhcTcId -> TcM (RuleDecl GhcTcId)
forall a b. (a -> b) -> a -> b
$ HsRule :: forall pass.
XHsRule pass
-> Located (SourceText, RuleName)
-> Activation
-> Maybe [LHsTyVarBndr (NoGhcTc pass)]
-> [LRuleBndr pass]
-> Located (HsExpr pass)
-> Located (HsExpr pass)
-> RuleDecl pass
HsRule { rd_ext :: XHsRule GhcTcId
rd_ext = XHsRule GhcRn
XHsRule GhcTcId
ext
, rd_name :: Located (SourceText, RuleName)
rd_name = Located (SourceText, RuleName)
rname
, rd_act :: Activation
rd_act = Activation
act
, rd_tyvs :: Maybe [LHsTyVarBndr (NoGhcTc GhcTcId)]
rd_tyvs = Maybe [LHsTyVarBndr (NoGhcTc GhcRn)]
Maybe [LHsTyVarBndr (NoGhcTc GhcTcId)]
ty_bndrs
, rd_tmvs :: [LRuleBndr GhcTcId]
rd_tmvs = (TyVar -> LRuleBndr GhcTcId) -> [TyVar] -> [LRuleBndr GhcTcId]
forall a b. (a -> b) -> [a] -> [b]
map (RuleBndr GhcTcId -> LRuleBndr GhcTcId
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (RuleBndr GhcTcId -> LRuleBndr GhcTcId)
-> (TyVar -> RuleBndr GhcTcId) -> TyVar -> LRuleBndr GhcTcId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XCRuleBndr GhcTcId -> Located (IdP GhcTcId) -> RuleBndr GhcTcId
forall pass. XCRuleBndr pass -> Located (IdP pass) -> RuleBndr pass
RuleBndr XCRuleBndr GhcTcId
NoExtField
noExtField (GenLocated SrcSpan TyVar -> RuleBndr GhcTcId)
-> (TyVar -> GenLocated SrcSpan TyVar) -> TyVar -> RuleBndr GhcTcId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVar -> GenLocated SrcSpan TyVar
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc)
([TyVar]
all_qtkvs [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
tpl_ids)
, rd_lhs :: LHsExpr GhcTcId
rd_lhs = TcEvBinds -> LHsExpr GhcTcId -> LHsExpr GhcTcId
mkHsDictLet TcEvBinds
lhs_binds LHsExpr GhcTcId
lhs'
, rd_rhs :: LHsExpr GhcTcId
rd_rhs = TcEvBinds -> LHsExpr GhcTcId -> LHsExpr GhcTcId
mkHsDictLet TcEvBinds
rhs_binds LHsExpr GhcTcId
rhs' } }
tcRule (XRuleDecl XXRuleDecl GhcRn
nec) = NoExtCon -> TcM (RuleDecl GhcTcId)
forall a. NoExtCon -> a
noExtCon XXRuleDecl GhcRn
NoExtCon
nec
generateRuleConstraints :: Maybe [LHsTyVarBndr GhcRn] -> [LRuleBndr GhcRn]
-> LHsExpr GhcRn -> LHsExpr GhcRn
-> TcM ( [TyVar]
, [TcId]
, LHsExpr GhcTc, WantedConstraints
, LHsExpr GhcTc, WantedConstraints
, TcType )
generateRuleConstraints :: Maybe [LHsTyVarBndr GhcRn]
-> [LRuleBndr GhcRn]
-> Located (HsExpr GhcRn)
-> Located (HsExpr GhcRn)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
generateRuleConstraints Maybe [LHsTyVarBndr GhcRn]
ty_bndrs [LRuleBndr GhcRn]
tm_bndrs Located (HsExpr GhcRn)
lhs Located (HsExpr GhcRn)
rhs
= do { (([TyVar]
tv_bndrs, [TyVar]
id_bndrs), WantedConstraints
bndr_wanted) <- TcM ([TyVar], [TyVar])
-> TcM (([TyVar], [TyVar]), WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints (TcM ([TyVar], [TyVar])
-> TcM (([TyVar], [TyVar]), WantedConstraints))
-> TcM ([TyVar], [TyVar])
-> TcM (([TyVar], [TyVar]), WantedConstraints)
forall a b. (a -> b) -> a -> b
$
Maybe [LHsTyVarBndr GhcRn]
-> [LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleBndrs Maybe [LHsTyVarBndr GhcRn]
ty_bndrs [LRuleBndr GhcRn]
tm_bndrs
; [TyVar]
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
forall r. [TyVar] -> TcM r -> TcM r
tcExtendTyVarEnv [TyVar]
tv_bndrs (TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType))
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
forall a b. (a -> b) -> a -> b
$
[TyVar]
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
forall r. [TyVar] -> TcM r -> TcM r
tcExtendIdEnv [TyVar]
id_bndrs (TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType))
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
forall a b. (a -> b) -> a -> b
$
do {
((LHsExpr GhcTcId
lhs', TcType
rule_ty), WantedConstraints
lhs_wanted) <- TcM (LHsExpr GhcTcId, TcType)
-> TcM ((LHsExpr GhcTcId, TcType), WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints (Located (HsExpr GhcRn) -> TcM (LHsExpr GhcTcId, TcType)
tcInferRho Located (HsExpr GhcRn)
lhs)
; (LHsExpr GhcTcId
rhs', WantedConstraints
rhs_wanted) <- TcM (LHsExpr GhcTcId) -> TcM (LHsExpr GhcTcId, WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints (TcM (LHsExpr GhcTcId) -> TcM (LHsExpr GhcTcId, WantedConstraints))
-> TcM (LHsExpr GhcTcId)
-> TcM (LHsExpr GhcTcId, WantedConstraints)
forall a b. (a -> b) -> a -> b
$
Located (HsExpr GhcRn) -> ExpRhoType -> TcM (LHsExpr GhcTcId)
tcMonoExpr Located (HsExpr GhcRn)
rhs (TcType -> ExpRhoType
mkCheckExpType TcType
rule_ty)
; let all_lhs_wanted :: WantedConstraints
all_lhs_wanted = WantedConstraints
bndr_wanted WantedConstraints -> WantedConstraints -> WantedConstraints
`andWC` WantedConstraints
lhs_wanted
; ([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
-> TcM
([TyVar], [TyVar], LHsExpr GhcTcId, WantedConstraints,
LHsExpr GhcTcId, WantedConstraints, TcType)
forall (m :: * -> *) a. Monad m => a -> m a
return ([TyVar]
tv_bndrs, [TyVar]
id_bndrs, LHsExpr GhcTcId
lhs', WantedConstraints
all_lhs_wanted, LHsExpr GhcTcId
rhs', WantedConstraints
rhs_wanted, TcType
rule_ty) } }
tcRuleBndrs :: Maybe [LHsTyVarBndr GhcRn] -> [LRuleBndr GhcRn]
-> TcM ([TcTyVar], [Id])
tcRuleBndrs :: Maybe [LHsTyVarBndr GhcRn]
-> [LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleBndrs (Just [LHsTyVarBndr GhcRn]
bndrs) [LRuleBndr GhcRn]
xs
= do { ([TyVar]
tys1,([TyVar]
tys2,[TyVar]
tms)) <- [LHsTyVarBndr GhcRn]
-> TcM ([TyVar], [TyVar]) -> TcM ([TyVar], ([TyVar], [TyVar]))
forall a. [LHsTyVarBndr GhcRn] -> TcM a -> TcM ([TyVar], a)
bindExplicitTKBndrs_Skol [LHsTyVarBndr GhcRn]
bndrs (TcM ([TyVar], [TyVar]) -> TcM ([TyVar], ([TyVar], [TyVar])))
-> TcM ([TyVar], [TyVar]) -> TcM ([TyVar], ([TyVar], [TyVar]))
forall a b. (a -> b) -> a -> b
$
[LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleTmBndrs [LRuleBndr GhcRn]
xs
; ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar])
forall (m :: * -> *) a. Monad m => a -> m a
return ([TyVar]
tys1 [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
tys2, [TyVar]
tms) }
tcRuleBndrs Maybe [LHsTyVarBndr GhcRn]
Nothing [LRuleBndr GhcRn]
xs
= [LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleTmBndrs [LRuleBndr GhcRn]
xs
tcRuleTmBndrs :: [LRuleBndr GhcRn] -> TcM ([TcTyVar],[Id])
tcRuleTmBndrs :: [LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleTmBndrs [] = ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar])
forall (m :: * -> *) a. Monad m => a -> m a
return ([],[])
tcRuleTmBndrs (L SrcSpan
_ (RuleBndr XCRuleBndr GhcRn
_ (L SrcSpan
_ IdP GhcRn
name)) : [LRuleBndr GhcRn]
rule_bndrs)
= do { TcType
ty <- TcM TcType
newOpenFlexiTyVarTy
; ([TyVar]
tyvars, [TyVar]
tmvars) <- [LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleTmBndrs [LRuleBndr GhcRn]
rule_bndrs
; ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar])
forall (m :: * -> *) a. Monad m => a -> m a
return ([TyVar]
tyvars, Name -> TcType -> TyVar
mkLocalId Name
IdP GhcRn
name TcType
ty TyVar -> [TyVar] -> [TyVar]
forall a. a -> [a] -> [a]
: [TyVar]
tmvars) }
tcRuleTmBndrs (L SrcSpan
_ (RuleBndrSig XRuleBndrSig GhcRn
_ (L SrcSpan
_ IdP GhcRn
name) LHsSigWcType GhcRn
rn_ty) : [LRuleBndr GhcRn]
rule_bndrs)
= do { let ctxt :: UserTypeCtxt
ctxt = Name -> UserTypeCtxt
RuleSigCtxt Name
IdP GhcRn
name
; ([(Name, TyVar)]
_ , [(Name, TyVar)]
tvs, TcType
id_ty) <- UserTypeCtxt
-> LHsSigWcType GhcRn
-> TcM ([(Name, TyVar)], [(Name, TyVar)], TcType)
tcHsPatSigType UserTypeCtxt
ctxt LHsSigWcType GhcRn
rn_ty
; let id :: TyVar
id = Name -> TcType -> TyVar
mkLocalIdOrCoVar Name
IdP GhcRn
name TcType
id_ty
; ([TyVar]
tyvars, [TyVar]
tmvars) <- [(Name, TyVar)] -> TcM ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar])
forall r. [(Name, TyVar)] -> TcM r -> TcM r
tcExtendNameTyVarEnv [(Name, TyVar)]
tvs (TcM ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar]))
-> TcM ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar])
forall a b. (a -> b) -> a -> b
$
[LRuleBndr GhcRn] -> TcM ([TyVar], [TyVar])
tcRuleTmBndrs [LRuleBndr GhcRn]
rule_bndrs
; ([TyVar], [TyVar]) -> TcM ([TyVar], [TyVar])
forall (m :: * -> *) a. Monad m => a -> m a
return (((Name, TyVar) -> TyVar) -> [(Name, TyVar)] -> [TyVar]
forall a b. (a -> b) -> [a] -> [b]
map (Name, TyVar) -> TyVar
forall a b. (a, b) -> b
snd [(Name, TyVar)]
tvs [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
tyvars, TyVar
id TyVar -> [TyVar] -> [TyVar]
forall a. a -> [a] -> [a]
: [TyVar]
tmvars) }
tcRuleTmBndrs (L SrcSpan
_ (XRuleBndr XXRuleBndr GhcRn
nec) : [LRuleBndr GhcRn]
_) = NoExtCon -> TcM ([TyVar], [TyVar])
forall a. NoExtCon -> a
noExtCon XXRuleBndr GhcRn
NoExtCon
nec
ruleCtxt :: FastString -> SDoc
ruleCtxt :: RuleName -> MsgDoc
ruleCtxt RuleName
name = String -> MsgDoc
text String
"When checking the transformation rule" MsgDoc -> MsgDoc -> MsgDoc
<+>
MsgDoc -> MsgDoc
doubleQuotes (RuleName -> MsgDoc
ftext RuleName
name)
simplifyRule :: RuleName
-> TcLevel
-> WantedConstraints
-> WantedConstraints
-> TcM ( [EvVar]
, WantedConstraints)
simplifyRule :: RuleName
-> TcLevel
-> WantedConstraints
-> WantedConstraints
-> TcM ([TyVar], WantedConstraints)
simplifyRule RuleName
name TcLevel
tc_lvl WantedConstraints
lhs_wanted WantedConstraints
rhs_wanted
= do {
; WantedConstraints
lhs_clone <- WantedConstraints -> TcM WantedConstraints
cloneWC WantedConstraints
lhs_wanted
; WantedConstraints
rhs_clone <- WantedConstraints -> TcM WantedConstraints
cloneWC WantedConstraints
rhs_wanted
; TcLevel -> TcRn () -> TcRn ()
forall a. TcLevel -> TcM a -> TcM a
setTcLevel TcLevel
tc_lvl (TcRn () -> TcRn ()) -> TcRn () -> TcRn ()
forall a b. (a -> b) -> a -> b
$
TcS () -> TcRn ()
forall a. TcS a -> TcM a
runTcSDeriveds (TcS () -> TcRn ()) -> TcS () -> TcRn ()
forall a b. (a -> b) -> a -> b
$
do { WantedConstraints
_ <- WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
lhs_clone
; WantedConstraints
_ <- WantedConstraints -> TcS WantedConstraints
solveWanteds WantedConstraints
rhs_clone
; () -> TcS ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }
; WantedConstraints
lhs_wanted <- WantedConstraints -> TcM WantedConstraints
zonkWC WantedConstraints
lhs_wanted
; let (Cts
quant_cts, WantedConstraints
residual_lhs_wanted) = WantedConstraints -> (Cts, WantedConstraints)
getRuleQuantCts WantedConstraints
lhs_wanted
; [TyVar]
quant_evs <- (Ct -> IOEnv (Env TcGblEnv TcLclEnv) TyVar) -> [Ct] -> TcM [TyVar]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Ct -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
mk_quant_ev (Cts -> [Ct]
forall a. Bag a -> [a]
bagToList Cts
quant_cts)
; String -> MsgDoc -> TcRn ()
traceTc String
"simplifyRule" (MsgDoc -> TcRn ()) -> MsgDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$
[MsgDoc] -> MsgDoc
vcat [ String -> MsgDoc
text String
"LHS of rule" MsgDoc -> MsgDoc -> MsgDoc
<+> MsgDoc -> MsgDoc
doubleQuotes (RuleName -> MsgDoc
ftext RuleName
name)
, String -> MsgDoc
text String
"lhs_wanted" MsgDoc -> MsgDoc -> MsgDoc
<+> WantedConstraints -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr WantedConstraints
lhs_wanted
, String -> MsgDoc
text String
"rhs_wanted" MsgDoc -> MsgDoc -> MsgDoc
<+> WantedConstraints -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr WantedConstraints
rhs_wanted
, String -> MsgDoc
text String
"quant_cts" MsgDoc -> MsgDoc -> MsgDoc
<+> Cts -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr Cts
quant_cts
, String -> MsgDoc
text String
"residual_lhs_wanted" MsgDoc -> MsgDoc -> MsgDoc
<+> WantedConstraints -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr WantedConstraints
residual_lhs_wanted
]
; ([TyVar], WantedConstraints) -> TcM ([TyVar], WantedConstraints)
forall (m :: * -> *) a. Monad m => a -> m a
return ([TyVar]
quant_evs, WantedConstraints
residual_lhs_wanted) }
where
mk_quant_ev :: Ct -> TcM EvVar
mk_quant_ev :: Ct -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
mk_quant_ev Ct
ct
| CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = TcEvDest
dest, ctev_pred :: CtEvidence -> TcType
ctev_pred = TcType
pred } <- Ct -> CtEvidence
ctEvidence Ct
ct
= case TcEvDest
dest of
EvVarDest TyVar
ev_id -> TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
forall (m :: * -> *) a. Monad m => a -> m a
return TyVar
ev_id
HoleDest CoercionHole
hole ->
do { TyVar
ev_id <- TcType -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
forall gbl lcl. TcType -> TcRnIf gbl lcl TyVar
newEvVar TcType
pred
; CoercionHole -> Coercion -> TcRn ()
fillCoercionHole CoercionHole
hole (TyVar -> Coercion
mkTcCoVarCo TyVar
ev_id)
; TyVar -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
forall (m :: * -> *) a. Monad m => a -> m a
return TyVar
ev_id }
mk_quant_ev Ct
ct = String -> MsgDoc -> IOEnv (Env TcGblEnv TcLclEnv) TyVar
forall a. HasCallStack => String -> MsgDoc -> a
pprPanic String
"mk_quant_ev" (Ct -> MsgDoc
forall a. Outputable a => a -> MsgDoc
ppr Ct
ct)
getRuleQuantCts :: WantedConstraints -> (Cts, WantedConstraints)
getRuleQuantCts :: WantedConstraints -> (Cts, WantedConstraints)
getRuleQuantCts WantedConstraints
wc
= TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints)
float_wc TcTyCoVarSet
emptyVarSet WantedConstraints
wc
where
float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints)
float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints)
float_wc TcTyCoVarSet
skol_tvs (WC { wc_simple :: WantedConstraints -> Cts
wc_simple = Cts
simples, wc_impl :: WantedConstraints -> Bag Implication
wc_impl = Bag Implication
implics })
= ( Cts
simple_yes Cts -> Cts -> Cts
`andCts` Cts
implic_yes
, WC :: Cts -> Bag Implication -> WantedConstraints
WC { wc_simple :: Cts
wc_simple = Cts
simple_no, wc_impl :: Bag Implication
wc_impl = Bag Implication
implics_no })
where
(Cts
simple_yes, Cts
simple_no) = (Ct -> Bool) -> Cts -> (Cts, Cts)
forall a. (a -> Bool) -> Bag a -> (Bag a, Bag a)
partitionBag (TcTyCoVarSet -> Ct -> Bool
rule_quant_ct TcTyCoVarSet
skol_tvs) Cts
simples
(Cts
implic_yes, Bag Implication
implics_no) = (Cts -> Implication -> (Cts, Implication))
-> Cts -> Bag Implication -> (Cts, Bag Implication)
forall acc x y.
(acc -> x -> (acc, y)) -> acc -> Bag x -> (acc, Bag y)
mapAccumBagL (TcTyCoVarSet -> Cts -> Implication -> (Cts, Implication)
float_implic TcTyCoVarSet
skol_tvs)
Cts
forall a. Bag a
emptyBag Bag Implication
implics
float_implic :: TcTyCoVarSet -> Cts -> Implication -> (Cts, Implication)
float_implic :: TcTyCoVarSet -> Cts -> Implication -> (Cts, Implication)
float_implic TcTyCoVarSet
skol_tvs Cts
yes1 Implication
imp
= (Cts
yes1 Cts -> Cts -> Cts
`andCts` Cts
yes2, Implication
imp { ic_wanted :: WantedConstraints
ic_wanted = WantedConstraints
no })
where
(Cts
yes2, WantedConstraints
no) = TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints)
float_wc TcTyCoVarSet
new_skol_tvs (Implication -> WantedConstraints
ic_wanted Implication
imp)
new_skol_tvs :: TcTyCoVarSet
new_skol_tvs = TcTyCoVarSet
skol_tvs TcTyCoVarSet -> [TyVar] -> TcTyCoVarSet
`extendVarSetList` Implication -> [TyVar]
ic_skols Implication
imp
rule_quant_ct :: TcTyCoVarSet -> Ct -> Bool
rule_quant_ct :: TcTyCoVarSet -> Ct -> Bool
rule_quant_ct TcTyCoVarSet
skol_tvs Ct
ct
| EqPred EqRel
_ TcType
t1 TcType
t2 <- TcType -> Pred
classifyPredType (Ct -> TcType
ctPred Ct
ct)
, Bool -> Bool
not (TcType -> TcType -> Bool
ok_eq TcType
t1 TcType
t2)
= Bool
False
| Ct -> Bool
isHoleCt Ct
ct
= Bool
False
| Bool
otherwise
= Ct -> TcTyCoVarSet
tyCoVarsOfCt Ct
ct TcTyCoVarSet -> TcTyCoVarSet -> Bool
`disjointVarSet` TcTyCoVarSet
skol_tvs
ok_eq :: TcType -> TcType -> Bool
ok_eq TcType
t1 TcType
t2
| TcType
t1 HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
`tcEqType` TcType
t2 = Bool
False
| Bool
otherwise = TcType -> Bool
is_fun_app TcType
t1 Bool -> Bool -> Bool
|| TcType -> Bool
is_fun_app TcType
t2
is_fun_app :: TcType -> Bool
is_fun_app TcType
ty
= case TcType -> Maybe TyCon
tyConAppTyCon_maybe TcType
ty of
Just TyCon
tc -> TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
Maybe TyCon
Nothing -> Bool
False