{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
module GHC.Tc.Solver.Rewrite(
rewrite, rewriteArgsNom,
rewriteType
) where
import GHC.Prelude
import GHC.Core.TyCo.Ppr ( pprTyVar )
import GHC.Tc.Types ( TcGblEnv(tcg_tc_plugin_rewriters),
TcPluginRewriter, TcPluginRewriteResult(..),
RewriteEnv(..),
runTcPluginM )
import GHC.Tc.Types.Constraint
import GHC.Core.Predicate
import GHC.Tc.Utils.TcType
import GHC.Core.Type
import GHC.Tc.Types.Evidence
import GHC.Core.TyCon
import GHC.Core.TyCo.Rep
import GHC.Core.Coercion
import GHC.Core.Reduction
import GHC.Types.Unique.FM
import GHC.Types.Var
import GHC.Types.Var.Set
import GHC.Types.Var.Env
import GHC.Driver.Session
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Utils.Panic.Plain
import GHC.Tc.Solver.Monad as TcS
import GHC.Utils.Misc
import GHC.Data.Maybe
import GHC.Exts (oneShot)
import Control.Monad
import Control.Applicative (liftA3)
import GHC.Builtin.Types.Prim (tYPETyCon)
import Data.List ( find )
newtype RewriteM a
= RewriteM { forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM :: RewriteEnv -> TcS a }
deriving (forall a b. a -> RewriteM b -> RewriteM a
forall a b. (a -> b) -> RewriteM a -> RewriteM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> RewriteM b -> RewriteM a
$c<$ :: forall a b. a -> RewriteM b -> RewriteM a
fmap :: forall a b. (a -> b) -> RewriteM a -> RewriteM b
$cfmap :: forall a b. (a -> b) -> RewriteM a -> RewriteM b
Functor)
mkRewriteM :: (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM :: forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM RewriteEnv -> TcS a
f = forall a. (RewriteEnv -> TcS a) -> RewriteM a
RewriteM (oneShot :: forall a b. (a -> b) -> a -> b
oneShot RewriteEnv -> TcS a
f)
{-# INLINE mkRewriteM #-}
instance Monad RewriteM where
RewriteM a
m >>= :: forall a b. RewriteM a -> (a -> RewriteM b) -> RewriteM b
>>= a -> RewriteM b
k = forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env ->
do { a
a <- forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
m RewriteEnv
env
; forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM (a -> RewriteM b
k a
a) RewriteEnv
env }
instance Applicative RewriteM where
pure :: forall a. a -> RewriteM a
pure a
x = forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
<*> :: forall a b. RewriteM (a -> b) -> RewriteM a -> RewriteM b
(<*>) = forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance HasDynFlags RewriteM where
getDynFlags :: RewriteM DynFlags
getDynFlags = forall a. TcS a -> RewriteM a
liftTcS forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
liftTcS :: TcS a -> RewriteM a
liftTcS :: forall a. TcS a -> RewriteM a
liftTcS TcS a
thing_inside
= forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
_ -> TcS a
thing_inside
runRewriteCtEv :: CtEvidence -> RewriteM a -> TcS (a, RewriterSet)
runRewriteCtEv :: forall a. CtEvidence -> RewriteM a -> TcS (a, RewriterSet)
runRewriteCtEv CtEvidence
ev
= forall a.
CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
runRewrite (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) (CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev) (CtEvidence -> EqRel
ctEvEqRel CtEvidence
ev)
runRewrite :: CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
runRewrite :: forall a.
CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
runRewrite CtLoc
loc CtFlavour
flav EqRel
eq_rel RewriteM a
thing_inside
= do { TcRef RewriterSet
rewriters_ref <- forall a. a -> TcS (TcRef a)
newTcRef RewriterSet
emptyRewriterSet
; let fmode :: RewriteEnv
fmode = RE { re_loc :: CtLoc
re_loc = CtLoc
loc
, re_flavour :: CtFlavour
re_flavour = CtFlavour
flav
, re_eq_rel :: EqRel
re_eq_rel = EqRel
eq_rel
, re_rewriters :: TcRef RewriterSet
re_rewriters = TcRef RewriterSet
rewriters_ref }
; a
res <- forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
thing_inside RewriteEnv
fmode
; RewriterSet
rewriters <- forall a. TcRef a -> TcS a
readTcRef TcRef RewriterSet
rewriters_ref
; forall (m :: * -> *) a. Monad m => a -> m a
return (a
res, RewriterSet
rewriters) }
traceRewriteM :: String -> SDoc -> RewriteM ()
traceRewriteM :: String -> SDoc -> RewriteM ()
traceRewriteM String
herald SDoc
doc = forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ String -> SDoc -> TcS ()
traceTcS String
herald SDoc
doc
{-# INLINE traceRewriteM #-}
getRewriteEnv :: RewriteM RewriteEnv
getRewriteEnv :: RewriteM RewriteEnv
getRewriteEnv
= forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> forall (m :: * -> *) a. Monad m => a -> m a
return RewriteEnv
env
getRewriteEnvField :: (RewriteEnv -> a) -> RewriteM a
getRewriteEnvField :: forall a. (RewriteEnv -> a) -> RewriteM a
getRewriteEnvField RewriteEnv -> a
accessor
= forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> forall (m :: * -> *) a. Monad m => a -> m a
return (RewriteEnv -> a
accessor RewriteEnv
env)
getEqRel :: RewriteM EqRel
getEqRel :: RewriteM EqRel
getEqRel = forall a. (RewriteEnv -> a) -> RewriteM a
getRewriteEnvField RewriteEnv -> EqRel
re_eq_rel
getRole :: RewriteM Role
getRole :: RewriteM Role
getRole = EqRel -> Role
eqRelRole forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RewriteM EqRel
getEqRel
getFlavour :: RewriteM CtFlavour
getFlavour :: RewriteM CtFlavour
getFlavour = forall a. (RewriteEnv -> a) -> RewriteM a
getRewriteEnvField RewriteEnv -> CtFlavour
re_flavour
getFlavourRole :: RewriteM CtFlavourRole
getFlavourRole :: RewriteM CtFlavourRole
getFlavourRole
= do { CtFlavour
flavour <- RewriteM CtFlavour
getFlavour
; EqRel
eq_rel <- RewriteM EqRel
getEqRel
; forall (m :: * -> *) a. Monad m => a -> m a
return (CtFlavour
flavour, EqRel
eq_rel) }
getLoc :: RewriteM CtLoc
getLoc :: RewriteM CtLoc
getLoc = forall a. (RewriteEnv -> a) -> RewriteM a
getRewriteEnvField RewriteEnv -> CtLoc
re_loc
checkStackDepth :: Type -> RewriteM ()
checkStackDepth :: Xi -> RewriteM ()
checkStackDepth Xi
ty
= do { CtLoc
loc <- RewriteM CtLoc
getLoc
; forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ CtLoc -> Xi -> TcS ()
checkReductionDepth CtLoc
loc Xi
ty }
setEqRel :: EqRel -> RewriteM a -> RewriteM a
setEqRel :: forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
new_eq_rel RewriteM a
thing_inside
= forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env ->
if EqRel
new_eq_rel forall a. Eq a => a -> a -> Bool
== RewriteEnv -> EqRel
re_eq_rel RewriteEnv
env
then forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
thing_inside RewriteEnv
env
else forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
thing_inside (RewriteEnv
env { re_eq_rel :: EqRel
re_eq_rel = EqRel
new_eq_rel })
{-# INLINE setEqRel #-}
bumpDepth :: RewriteM a -> RewriteM a
bumpDepth :: forall a. RewriteM a -> RewriteM a
bumpDepth (RewriteM RewriteEnv -> TcS a
thing_inside)
= forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> do
{ let !env' :: RewriteEnv
env' = RewriteEnv
env { re_loc :: CtLoc
re_loc = CtLoc -> CtLoc
bumpCtLocDepth (RewriteEnv -> CtLoc
re_loc RewriteEnv
env) }
; RewriteEnv -> TcS a
thing_inside RewriteEnv
env' }
recordRewriter :: CtEvidence -> RewriteM ()
recordRewriter :: CtEvidence -> RewriteM ()
recordRewriter (CtWanted { ctev_dest :: CtEvidence -> TcEvDest
ctev_dest = HoleDest CoercionHole
hole })
= forall a. (RewriteEnv -> TcS a) -> RewriteM a
RewriteM forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> forall a. TcRef a -> (a -> a) -> TcS ()
updTcRef (RewriteEnv -> TcRef RewriterSet
re_rewriters RewriteEnv
env) (RewriterSet -> CoercionHole -> RewriterSet
`addRewriterSet` CoercionHole
hole)
recordRewriter CtEvidence
other = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"recordRewriter" (forall a. Outputable a => a -> SDoc
ppr CtEvidence
other)
rewrite :: CtEvidence -> TcType
-> TcS (Reduction, RewriterSet)
rewrite :: CtEvidence -> Xi -> TcS (Reduction, RewriterSet)
rewrite CtEvidence
ev Xi
ty
= do { String -> SDoc -> TcS ()
traceTcS String
"rewrite {" (forall a. Outputable a => a -> SDoc
ppr Xi
ty)
; result :: (Reduction, RewriterSet)
result@(Reduction
redn, RewriterSet
_) <- forall a. CtEvidence -> RewriteM a -> TcS (a, RewriterSet)
runRewriteCtEv CtEvidence
ev (Xi -> RewriteM Reduction
rewrite_one Xi
ty)
; String -> SDoc -> TcS ()
traceTcS String
"rewrite }" (forall a. Outputable a => a -> SDoc
ppr forall a b. (a -> b) -> a -> b
$ Reduction -> Xi
reductionReducedType Reduction
redn)
; forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction, RewriterSet)
result }
rewriteArgsNom :: CtEvidence -> TyCon -> [TcType]
-> TcS (Reductions, RewriterSet)
rewriteArgsNom :: CtEvidence -> TyCon -> [Xi] -> TcS (Reductions, RewriterSet)
rewriteArgsNom CtEvidence
ev TyCon
tc [Xi]
tys
= do { String -> SDoc -> TcS ()
traceTcS String
"rewrite_args {" ([SDoc] -> SDoc
vcat (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> SDoc
ppr [Xi]
tys))
; (ArgsReductions redns :: Reductions
redns@(Reductions [Coercion]
_ [Xi]
tys') MCoercionN
kind_co, RewriterSet
rewriters)
<- forall a. CtEvidence -> RewriteM a -> TcS (a, RewriterSet)
runRewriteCtEv CtEvidence
ev (TyCon -> Maybe [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc forall a. Maybe a
Nothing [Xi]
tys)
; forall (m :: * -> *). (HasCallStack, Applicative m) => Bool -> m ()
massert (MCoercionN -> Bool
isReflMCo MCoercionN
kind_co)
; String -> SDoc -> TcS ()
traceTcS String
"rewrite }" ([SDoc] -> SDoc
vcat (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> SDoc
ppr [Xi]
tys'))
; forall (m :: * -> *) a. Monad m => a -> m a
return (Reductions
redns, RewriterSet
rewriters) }
rewriteType :: CtLoc -> TcType -> TcS TcType
rewriteType :: CtLoc -> Xi -> TcS Xi
rewriteType CtLoc
loc Xi
ty
= do { (Reduction
redn, RewriterSet
_) <- forall a.
CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
runRewrite CtLoc
loc CtFlavour
Given EqRel
NomEq forall a b. (a -> b) -> a -> b
$
Xi -> RewriteM Reduction
rewrite_one Xi
ty
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Reduction -> Xi
reductionReducedType Reduction
redn }
{-# INLINE rewrite_args_tc #-}
rewrite_args_tc
:: TyCon
-> Maybe [Role]
-> [Type]
-> RewriteM ArgsReductions
rewrite_args_tc :: TyCon -> Maybe [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc = [TyCoBinder]
-> Bool
-> Xi
-> TcTyCoVarSet
-> Maybe [Role]
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args [TyCoBinder]
all_bndrs Bool
any_named_bndrs Xi
inner_ki TcTyCoVarSet
emptyVarSet
where
([TyCoBinder]
bndrs, Bool
named)
= [TyConBinder] -> ([TyCoBinder], Bool)
ty_con_binders_ty_binders' (TyCon -> [TyConBinder]
tyConBinders TyCon
tc)
([TyCoBinder]
inner_bndrs, Xi
inner_ki, Bool
inner_named) = Xi -> ([TyCoBinder], Xi, Bool)
split_pi_tys' (TyCon -> Xi
tyConResKind TyCon
tc)
!all_bndrs :: [TyCoBinder]
all_bndrs = [TyCoBinder]
bndrs forall a. [a] -> [a] -> [a]
`chkAppend` [TyCoBinder]
inner_bndrs
!any_named_bndrs :: Bool
any_named_bndrs = Bool
named Bool -> Bool -> Bool
|| Bool
inner_named
{-# INLINE rewrite_args #-}
rewrite_args :: [TyCoBinder] -> Bool
-> Kind -> TcTyCoVarSet
-> Maybe [Role] -> [Type]
-> RewriteM ArgsReductions
rewrite_args :: [TyCoBinder]
-> Bool
-> Xi
-> TcTyCoVarSet
-> Maybe [Role]
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args [TyCoBinder]
orig_binders
Bool
any_named_bndrs
Xi
orig_inner_ki
TcTyCoVarSet
orig_fvs
Maybe [Role]
orig_m_roles
[Xi]
orig_tys
= case (Maybe [Role]
orig_m_roles, Bool
any_named_bndrs) of
(Maybe [Role]
Nothing, Bool
False) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_fast [Xi]
orig_tys
(Maybe [Role], Bool)
_ -> [TyCoBinder]
-> Xi -> TcTyCoVarSet -> [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_slow [TyCoBinder]
orig_binders Xi
orig_inner_ki TcTyCoVarSet
orig_fvs [Role]
orig_roles [Xi]
orig_tys
where orig_roles :: [Role]
orig_roles = forall a. a -> Maybe a -> a
fromMaybe (forall a. a -> [a]
repeat Role
Nominal) Maybe [Role]
orig_m_roles
{-# INLINE rewrite_args_fast #-}
rewrite_args_fast :: [Type] -> RewriteM ArgsReductions
rewrite_args_fast :: [Xi] -> RewriteM ArgsReductions
rewrite_args_fast [Xi]
orig_tys
= forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Reductions -> ArgsReductions
finish ([Xi] -> RewriteM Reductions
iterate [Xi]
orig_tys)
where
iterate :: [Type] -> RewriteM Reductions
iterate :: [Xi] -> RewriteM Reductions
iterate (Xi
ty : [Xi]
tys) = do
Reduction Coercion
co Xi
xi <- Xi -> RewriteM Reduction
rewrite_one Xi
ty
Reductions [Coercion]
cos [Xi]
xis <- [Xi] -> RewriteM Reductions
iterate [Xi]
tys
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ [Coercion] -> [Xi] -> Reductions
Reductions (Coercion
co forall a. a -> [a] -> [a]
: [Coercion]
cos) (Xi
xi forall a. a -> [a] -> [a]
: [Xi]
xis)
iterate [] = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ [Coercion] -> [Xi] -> Reductions
Reductions [] []
{-# INLINE finish #-}
finish :: Reductions -> ArgsReductions
finish :: Reductions -> ArgsReductions
finish Reductions
redns = Reductions -> MCoercionN -> ArgsReductions
ArgsReductions Reductions
redns MCoercionN
MRefl
{-# INLINE rewrite_args_slow #-}
rewrite_args_slow :: [TyCoBinder] -> Kind -> TcTyCoVarSet
-> [Role] -> [Type]
-> RewriteM ArgsReductions
rewrite_args_slow :: [TyCoBinder]
-> Xi -> TcTyCoVarSet -> [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_slow [TyCoBinder]
binders Xi
inner_ki TcTyCoVarSet
fvs [Role]
roles [Xi]
tys
= do { [Reduction]
rewritten_args <- forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM Role -> Xi -> RewriteM Reduction
rw [Role]
roles [Xi]
tys
; forall (m :: * -> *) a. Monad m => a -> m a
return (HasDebugCallStack =>
[TyCoBinder]
-> Xi -> TcTyCoVarSet -> [Role] -> [Reduction] -> ArgsReductions
simplifyArgsWorker [TyCoBinder]
binders Xi
inner_ki TcTyCoVarSet
fvs [Role]
roles [Reduction]
rewritten_args) }
where
{-# INLINE rw #-}
rw :: Role -> Type -> RewriteM Reduction
rw :: Role -> Xi -> RewriteM Reduction
rw Role
Nominal Xi
ty
= forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
NomEq forall a b. (a -> b) -> a -> b
$
Xi -> RewriteM Reduction
rewrite_one Xi
ty
rw Role
Representational Xi
ty
= forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
ReprEq forall a b. (a -> b) -> a -> b
$
Xi -> RewriteM Reduction
rewrite_one Xi
ty
rw Role
Phantom Xi
ty
= do { Xi
ty <- forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ Xi -> TcS Xi
zonkTcType Xi
ty
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role -> Xi -> Reduction
mkReflRedn Role
Phantom Xi
ty }
rewrite_one :: TcType -> RewriteM Reduction
rewrite_one :: Xi -> RewriteM Reduction
rewrite_one Xi
ty
| Just Xi
ty' <- Xi -> Maybe Xi
rewriterView Xi
ty
= Xi -> RewriteM Reduction
rewrite_one Xi
ty'
rewrite_one xi :: Xi
xi@(LitTy {})
= do { Role
role <- RewriteM Role
getRole
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role -> Xi -> Reduction
mkReflRedn Role
role Xi
xi }
rewrite_one (TyVarTy TcTyVar
tv)
= TcTyVar -> RewriteM Reduction
rewriteTyVar TcTyVar
tv
rewrite_one (AppTy Xi
ty1 Xi
ty2)
= Xi -> [Xi] -> RewriteM Reduction
rewrite_app_tys Xi
ty1 [Xi
ty2]
rewrite_one (TyConApp TyCon
tc [Xi]
tys)
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
= TyCon -> [Xi] -> RewriteM Reduction
rewrite_fam_app TyCon
tc [Xi]
tys
| Bool
otherwise
= TyCon -> [Xi] -> RewriteM Reduction
rewrite_ty_con_app TyCon
tc [Xi]
tys
rewrite_one (FunTy { ft_af :: Xi -> AnonArgFlag
ft_af = AnonArgFlag
vis, ft_mult :: Xi -> Xi
ft_mult = Xi
mult, ft_arg :: Xi -> Xi
ft_arg = Xi
ty1, ft_res :: Xi -> Xi
ft_res = Xi
ty2 })
= do { Reduction
arg_redn <- Xi -> RewriteM Reduction
rewrite_one Xi
ty1
; Reduction
res_redn <- Xi -> RewriteM Reduction
rewrite_one Xi
ty2
; let arg_rep :: Xi
arg_rep = HasDebugCallStack => Xi -> Xi
getRuntimeRep (Reduction -> Xi
reductionReducedType Reduction
arg_redn)
res_rep :: Xi
res_rep = HasDebugCallStack => Xi -> Xi
getRuntimeRep (Reduction -> Xi
reductionReducedType Reduction
res_redn)
; (Reduction
w_redn, Reduction
arg_rep_redn, Reduction
res_rep_redn) <- forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
NomEq forall a b. (a -> b) -> a -> b
$
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 (,,) (Xi -> RewriteM Reduction
rewrite_one Xi
mult)
(Xi -> RewriteM Reduction
rewrite_one Xi
arg_rep)
(Xi -> RewriteM Reduction
rewrite_one Xi
res_rep)
; Role
role <- RewriteM Role
getRole
; let arg_rep_co :: Coercion
arg_rep_co = Reduction -> Coercion
reductionCoercion Reduction
arg_rep_redn
arg_ki_co :: Coercion
arg_ki_co = HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
Nominal TyCon
tYPETyCon [Coercion
arg_rep_co]
casted_arg_redn :: Reduction
casted_arg_redn = Role -> Reduction -> Coercion -> Reduction
mkCoherenceRightRedn Role
role Reduction
arg_redn Coercion
arg_ki_co
res_rep_co :: Coercion
res_rep_co = Reduction -> Coercion
reductionCoercion Reduction
res_rep_redn
res_ki_co :: Coercion
res_ki_co = HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
Nominal TyCon
tYPETyCon [Coercion
res_rep_co]
casted_res_redn :: Reduction
casted_res_redn = Role -> Reduction -> Coercion -> Reduction
mkCoherenceRightRedn Role
role Reduction
res_redn Coercion
res_ki_co
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role
-> AnonArgFlag -> Reduction -> Reduction -> Reduction -> Reduction
mkFunRedn Role
role AnonArgFlag
vis Reduction
w_redn Reduction
casted_arg_redn Reduction
casted_res_redn }
rewrite_one ty :: Xi
ty@(ForAllTy {})
= do { let ([TyVarBinder]
bndrs, Xi
rho) = Xi -> ([TyVarBinder], Xi)
tcSplitForAllTyVarBinders Xi
ty
; Reduction
redn <- Xi -> RewriteM Reduction
rewrite_one Xi
rho
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [TyVarBinder] -> Reduction -> Reduction
mkHomoForAllRedn [TyVarBinder]
bndrs Reduction
redn }
rewrite_one (CastTy Xi
ty Coercion
g)
= do { Reduction
redn <- Xi -> RewriteM Reduction
rewrite_one Xi
ty
; Coercion
g' <- Coercion -> RewriteM Coercion
rewrite_co Coercion
g
; Role
role <- RewriteM Role
getRole
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role -> Xi -> Coercion -> Reduction -> Reduction
mkCastRedn1 Role
role Xi
ty Coercion
g' Reduction
redn }
rewrite_one (CoercionTy Coercion
co)
= do { Coercion
co' <- Coercion -> RewriteM Coercion
rewrite_co Coercion
co
; Role
role <- RewriteM Role
getRole
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role -> Coercion -> Reduction
mkReflCoRedn Role
role Coercion
co' }
rewrite_co :: Coercion -> RewriteM Coercion
rewrite_co :: Coercion -> RewriteM Coercion
rewrite_co Coercion
co = forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ Coercion -> TcS Coercion
zonkCo Coercion
co
rewrite_reduction :: Reduction -> RewriteM Reduction
rewrite_reduction :: Reduction -> RewriteM Reduction
rewrite_reduction (Reduction Coercion
co Xi
xi)
= do { Reduction
redn <- forall a. RewriteM a -> RewriteM a
bumpDepth forall a b. (a -> b) -> a -> b
$ Xi -> RewriteM Reduction
rewrite_one Xi
xi
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Coercion
co Coercion -> Reduction -> Reduction
`mkTransRedn` Reduction
redn }
rewrite_app_tys :: Type -> [Type] -> RewriteM Reduction
rewrite_app_tys :: Xi -> [Xi] -> RewriteM Reduction
rewrite_app_tys (AppTy Xi
ty1 Xi
ty2) [Xi]
tys = Xi -> [Xi] -> RewriteM Reduction
rewrite_app_tys Xi
ty1 (Xi
ty2forall a. a -> [a] -> [a]
:[Xi]
tys)
rewrite_app_tys Xi
fun_ty [Xi]
arg_tys
= do { Reduction
redn <- Xi -> RewriteM Reduction
rewrite_one Xi
fun_ty
; Reduction -> [Xi] -> RewriteM Reduction
rewrite_app_ty_args Reduction
redn [Xi]
arg_tys }
rewrite_app_ty_args :: Reduction -> [Type] -> RewriteM Reduction
rewrite_app_ty_args :: Reduction -> [Xi] -> RewriteM Reduction
rewrite_app_ty_args Reduction
redn []
= forall (m :: * -> *) a. Monad m => a -> m a
return Reduction
redn
rewrite_app_ty_args fun_redn :: Reduction
fun_redn@(Reduction Coercion
fun_co Xi
fun_xi) [Xi]
arg_tys
= do { HetReduction
het_redn <- case HasCallStack => Xi -> Maybe (TyCon, [Xi])
tcSplitTyConApp_maybe Xi
fun_xi of
Just (TyCon
tc, [Xi]
xis) ->
do { let tc_roles :: [Role]
tc_roles = TyCon -> [Role]
tyConRolesRepresentational TyCon
tc
arg_roles :: [Role]
arg_roles = forall b a. [b] -> [a] -> [a]
dropList [Xi]
xis [Role]
tc_roles
; ArgsReductions (Reductions [Coercion]
arg_cos [Xi]
arg_xis) MCoercionN
kind_co
<- Xi -> [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_vector (HasDebugCallStack => Xi -> Xi
tcTypeKind Xi
fun_xi) [Role]
arg_roles [Xi]
arg_tys
; EqRel
eq_rel <- RewriteM EqRel
getEqRel
; let app_xi :: Xi
app_xi = TyCon -> [Xi] -> Xi
mkTyConApp TyCon
tc ([Xi]
xis forall a. [a] -> [a] -> [a]
++ [Xi]
arg_xis)
app_co :: Coercion
app_co = case EqRel
eq_rel of
EqRel
NomEq -> Coercion -> [Coercion] -> Coercion
mkAppCos Coercion
fun_co [Coercion]
arg_cos
EqRel
ReprEq -> Coercion -> [Coercion] -> Coercion
mkAppCos Coercion
fun_co (forall a b. (a -> b) -> [a] -> [b]
map Xi -> Coercion
mkNomReflCo [Xi]
arg_tys)
Coercion -> Coercion -> Coercion
`mkTcTransCo`
Role -> TyCon -> [Coercion] -> Coercion
mkTcTyConAppCo Role
Representational TyCon
tc
(forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Role -> Xi -> Coercion
mkReflCo [Role]
tc_roles [Xi]
xis forall a. [a] -> [a] -> [a]
++ [Coercion]
arg_cos)
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
Reduction -> MCoercionN -> HetReduction
mkHetReduction
(Coercion -> Xi -> Reduction
mkReduction Coercion
app_co Xi
app_xi )
MCoercionN
kind_co }
Maybe (TyCon, [Xi])
Nothing ->
do { ArgsReductions Reductions
redns MCoercionN
kind_co
<- Xi -> [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_vector (HasDebugCallStack => Xi -> Xi
tcTypeKind Xi
fun_xi) (forall a. a -> [a]
repeat Role
Nominal) [Xi]
arg_tys
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Reduction -> MCoercionN -> HetReduction
mkHetReduction (Reduction -> Reductions -> Reduction
mkAppRedns Reduction
fun_redn Reductions
redns) MCoercionN
kind_co }
; Role
role <- RewriteM Role
getRole
; forall (m :: * -> *) a. Monad m => a -> m a
return (Role -> HetReduction -> Reduction
homogeniseHetRedn Role
role HetReduction
het_redn) }
rewrite_ty_con_app :: TyCon -> [TcType] -> RewriteM Reduction
rewrite_ty_con_app :: TyCon -> [Xi] -> RewriteM Reduction
rewrite_ty_con_app TyCon
tc [Xi]
tys
= do { Role
role <- RewriteM Role
getRole
; let m_roles :: Maybe [Role]
m_roles | Role
Nominal <- Role
role = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Role -> TyCon -> [Role]
tyConRolesX Role
role TyCon
tc
; ArgsReductions Reductions
redns MCoercionN
kind_co <- TyCon -> Maybe [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc Maybe [Role]
m_roles [Xi]
tys
; let tyconapp_redn :: HetReduction
tyconapp_redn
= Reduction -> MCoercionN -> HetReduction
mkHetReduction
(Role -> TyCon -> Reductions -> Reduction
mkTyConAppRedn Role
role TyCon
tc Reductions
redns)
MCoercionN
kind_co
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role -> HetReduction -> Reduction
homogeniseHetRedn Role
role HetReduction
tyconapp_redn }
rewrite_vector :: Kind
-> [Role]
-> [Type]
-> RewriteM ArgsReductions
rewrite_vector :: Xi -> [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_vector Xi
ki [Role]
roles [Xi]
tys
= do { EqRel
eq_rel <- RewriteM EqRel
getEqRel
; let mb_roles :: Maybe [Role]
mb_roles = case EqRel
eq_rel of { EqRel
NomEq -> forall a. Maybe a
Nothing; EqRel
ReprEq -> forall a. a -> Maybe a
Just [Role]
roles }
; [TyCoBinder]
-> Bool
-> Xi
-> TcTyCoVarSet
-> Maybe [Role]
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args [TyCoBinder]
bndrs Bool
any_named_bndrs Xi
inner_ki TcTyCoVarSet
fvs Maybe [Role]
mb_roles [Xi]
tys
}
where
([TyCoBinder]
bndrs, Xi
inner_ki, Bool
any_named_bndrs) = Xi -> ([TyCoBinder], Xi, Bool)
split_pi_tys' Xi
ki
fvs :: TcTyCoVarSet
fvs = Xi -> TcTyCoVarSet
tyCoVarsOfType Xi
ki
{-# INLINE rewrite_vector #-}
rewrite_fam_app :: TyCon -> [TcType] -> RewriteM Reduction
rewrite_fam_app :: TyCon -> [Xi] -> RewriteM Reduction
rewrite_fam_app TyCon
tc [Xi]
tys
= forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr ([Xi]
tys forall a. [a] -> Arity -> Bool
`lengthAtLeast` TyCon -> Arity
tyConArity TyCon
tc)
(forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
$$ forall a. Outputable a => a -> SDoc
ppr (TyCon -> Arity
tyConArity TyCon
tc) SDoc -> SDoc -> SDoc
$$ forall a. Outputable a => a -> SDoc
ppr [Xi]
tys) forall a b. (a -> b) -> a -> b
$
do { let ([Xi]
tys1, [Xi]
tys_rest) = forall a. Arity -> [a] -> ([a], [a])
splitAt (TyCon -> Arity
tyConArity TyCon
tc) [Xi]
tys
; Reduction
redn <- TyCon -> [Xi] -> RewriteM Reduction
rewrite_exact_fam_app TyCon
tc [Xi]
tys1
; Reduction -> [Xi] -> RewriteM Reduction
rewrite_app_ty_args Reduction
redn [Xi]
tys_rest }
rewrite_exact_fam_app :: TyCon -> [TcType] -> RewriteM Reduction
rewrite_exact_fam_app :: TyCon -> [Xi] -> RewriteM Reduction
rewrite_exact_fam_app TyCon
tc [Xi]
tys
= do { Xi -> RewriteM ()
checkStackDepth (TyCon -> [Xi] -> Xi
mkTyConApp TyCon
tc [Xi]
tys)
; [TcPluginRewriter]
tc_rewriters <- TyCon -> RewriteM [TcPluginRewriter]
getTcPluginRewritersForTyCon TyCon
tc
; Maybe Reduction
result1 <- TyCon -> [Xi] -> [TcPluginRewriter] -> RewriteM (Maybe Reduction)
try_to_reduce TyCon
tc [Xi]
tys [TcPluginRewriter]
tc_rewriters
; case Maybe Reduction
result1 of
{ Just Reduction
redn -> Bool -> Reduction -> RewriteM Reduction
finish Bool
False Reduction
redn
; Maybe Reduction
Nothing ->
do { EqRel
eq_rel <- RewriteM EqRel
getEqRel
; ArgsReductions (Reductions [Coercion]
cos [Xi]
xis) MCoercionN
kind_co <-
if EqRel
eq_rel forall a. Eq a => a -> a -> Bool
== EqRel
NomEq
then TyCon -> Maybe [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc forall a. Maybe a
Nothing [Xi]
tys
else forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
NomEq forall a b. (a -> b) -> a -> b
$
TyCon -> Maybe [Role] -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc forall a. Maybe a
Nothing [Xi]
tys
; let
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
args_co :: Coercion
args_co = HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
role TyCon
tc [Coercion]
cos
; let homogenise :: Reduction -> Reduction
homogenise :: Reduction -> Reduction
homogenise Reduction
redn
= Role -> HetReduction -> Reduction
homogeniseHetRedn Role
role
forall a b. (a -> b) -> a -> b
$ Reduction -> MCoercionN -> HetReduction
mkHetReduction
(Coercion
args_co Coercion -> Reduction -> Reduction
`mkTransRedn` Reduction
redn)
MCoercionN
kind_co
give_up :: Reduction
give_up :: Reduction
give_up = Reduction -> Reduction
homogenise forall a b. (a -> b) -> a -> b
$ Role -> Xi -> Reduction
mkReflRedn Role
role Xi
reduced
where reduced :: Xi
reduced = TyCon -> [Xi] -> Xi
mkTyConApp TyCon
tc [Xi]
xis
; CtFlavour
flavour <- RewriteM CtFlavour
getFlavour
; Maybe (Reduction, CtFlavourRole)
result2 <- forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ (CtFlavourRole -> Bool)
-> TyCon -> [Xi] -> TcS (Maybe (Reduction, CtFlavourRole))
lookupFamAppInert (CtFlavourRole -> CtFlavourRole -> Bool
`eqCanRewriteFR` (CtFlavour
flavour, EqRel
eq_rel)) TyCon
tc [Xi]
xis
; case Maybe (Reduction, CtFlavourRole)
result2 of
{ Just (Reduction
redn, (CtFlavour
inert_flavour, EqRel
inert_eq_rel))
-> do { String -> SDoc -> RewriteM ()
traceRewriteM String
"rewrite family application with inert"
(forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
<+> forall a. Outputable a => a -> SDoc
ppr [Xi]
xis SDoc -> SDoc -> SDoc
$$ forall a. Outputable a => a -> SDoc
ppr Reduction
redn)
; Bool -> Reduction -> RewriteM Reduction
finish (CtFlavour
inert_flavour forall a. Eq a => a -> a -> Bool
== CtFlavour
Given) (Reduction -> Reduction
homogenise Reduction
downgraded_redn) }
where
inert_role :: Role
inert_role = EqRel -> Role
eqRelRole EqRel
inert_eq_rel
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
downgraded_redn :: Reduction
downgraded_redn = Role -> Role -> Reduction -> Reduction
downgradeRedn Role
role Role
inert_role Reduction
redn
; Maybe (Reduction, CtFlavourRole)
_ ->
do { Maybe Reduction
result3 <- TyCon -> [Xi] -> [TcPluginRewriter] -> RewriteM (Maybe Reduction)
try_to_reduce TyCon
tc [Xi]
xis [TcPluginRewriter]
tc_rewriters
; case Maybe Reduction
result3 of
Just Reduction
redn -> Bool -> Reduction -> RewriteM Reduction
finish Bool
True (Reduction -> Reduction
homogenise Reduction
redn)
Maybe Reduction
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Reduction
give_up }}}}}
where
finish :: Bool
-> Reduction -> RewriteM Reduction
finish :: Bool -> Reduction -> RewriteM Reduction
finish Bool
use_cache Reduction
redn
= do {
Reduction
final_redn <- Reduction -> RewriteM Reduction
rewrite_reduction Reduction
redn
; EqRel
eq_rel <- RewriteM EqRel
getEqRel
; forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
use_cache Bool -> Bool -> Bool
&& EqRel
eq_rel forall a. Eq a => a -> a -> Bool
== EqRel
NomEq) forall a b. (a -> b) -> a -> b
$
forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ TyCon -> [Xi] -> Reduction -> TcS ()
extendFamAppCache TyCon
tc [Xi]
tys Reduction
final_redn
; forall (m :: * -> *) a. Monad m => a -> m a
return Reduction
final_redn }
{-# INLINE finish #-}
try_to_reduce :: TyCon -> [TcType] -> [TcPluginRewriter]
-> RewriteM (Maybe Reduction)
try_to_reduce :: TyCon -> [Xi] -> [TcPluginRewriter] -> RewriteM (Maybe Reduction)
try_to_reduce TyCon
tc [Xi]
tys [TcPluginRewriter]
tc_rewriters
= do { RewriteEnv
rewrite_env <- RewriteM RewriteEnv
getRewriteEnv
; Maybe Reduction
result <-
forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f (m (Maybe a)) -> m (Maybe a)
firstJustsM
[ RewriteEnv -> [TcPluginRewriter] -> [Xi] -> TcS (Maybe Reduction)
runTcPluginRewriters RewriteEnv
rewrite_env [TcPluginRewriter]
tc_rewriters [Xi]
tys
, TyCon -> [Xi] -> TcS (Maybe Reduction)
lookupFamAppCache TyCon
tc [Xi]
tys
, TyCon -> [Xi] -> TcS (Maybe Reduction)
matchFam TyCon
tc [Xi]
tys ]
; forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Reduction -> RewriteM Reduction
downgrade Maybe Reduction
result }
where
downgrade :: Reduction -> RewriteM Reduction
downgrade :: Reduction -> RewriteM Reduction
downgrade Reduction
redn
= do { String -> SDoc -> RewriteM ()
traceRewriteM String
"Eager T.F. reduction success" forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ forall a. Outputable a => a -> SDoc
ppr TyCon
tc
, forall a. Outputable a => a -> SDoc
ppr [Xi]
tys
, forall a. Outputable a => a -> SDoc
ppr Reduction
redn
]
; EqRel
eq_rel <- RewriteM EqRel
getEqRel
; case EqRel
eq_rel of
EqRel
NomEq -> forall (m :: * -> *) a. Monad m => a -> m a
return Reduction
redn
EqRel
ReprEq -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Reduction -> Reduction
mkSubRedn Reduction
redn }
getTcPluginRewritersForTyCon :: TyCon -> RewriteM [TcPluginRewriter]
getTcPluginRewritersForTyCon :: TyCon -> RewriteM [TcPluginRewriter]
getTcPluginRewritersForTyCon TyCon
tc
= forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ do { UniqFM TyCon [TcPluginRewriter]
rewriters <- TcGblEnv -> UniqFM TyCon [TcPluginRewriter]
tcg_tc_plugin_rewriters forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TcS TcGblEnv
getGblEnv
; forall (m :: * -> *) a. Monad m => a -> m a
return (forall key elt.
Uniquable key =>
UniqFM key elt -> elt -> key -> elt
lookupWithDefaultUFM UniqFM TyCon [TcPluginRewriter]
rewriters [] TyCon
tc) }
runTcPluginRewriters :: RewriteEnv
-> [TcPluginRewriter]
-> [TcType]
-> TcS (Maybe Reduction)
runTcPluginRewriters :: RewriteEnv -> [TcPluginRewriter] -> [Xi] -> TcS (Maybe Reduction)
runTcPluginRewriters RewriteEnv
rewriteEnv [TcPluginRewriter]
rewriterFunctions [Xi]
tys
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcPluginRewriter]
rewriterFunctions
= forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Bool
otherwise
= do { [Ct]
givens <- TcS [Ct]
getInertGivens
; [Ct] -> [TcPluginRewriter] -> TcS (Maybe Reduction)
runRewriters [Ct]
givens [TcPluginRewriter]
rewriterFunctions }
where
runRewriters :: [Ct] -> [TcPluginRewriter] -> TcS (Maybe Reduction)
runRewriters :: [Ct] -> [TcPluginRewriter] -> TcS (Maybe Reduction)
runRewriters [Ct]
_ []
= forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
runRewriters [Ct]
givens (TcPluginRewriter
rewriter:[TcPluginRewriter]
rewriters)
= do
TcPluginRewriteResult
rewriteResult <- forall a. TcM a -> TcS a
wrapTcS forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TcPluginM a -> TcM a
runTcPluginM forall a b. (a -> b) -> a -> b
$ TcPluginRewriter
rewriter RewriteEnv
rewriteEnv [Ct]
givens [Xi]
tys
case TcPluginRewriteResult
rewriteResult of
TcPluginRewriteTo
{ tcPluginReduction :: TcPluginRewriteResult -> Reduction
tcPluginReduction = Reduction
redn
, tcRewriterNewWanteds :: TcPluginRewriteResult -> [Ct]
tcRewriterNewWanteds = [Ct]
wanteds
} -> do { [Ct] -> TcS ()
emitWork [Ct]
wanteds; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Reduction
redn }
TcPluginNoRewrite {} -> [Ct] -> [TcPluginRewriter] -> TcS (Maybe Reduction)
runRewriters [Ct]
givens [TcPluginRewriter]
rewriters
data RewriteTvResult
= RTRNotFollowed
| RTRFollowed !Reduction
rewriteTyVar :: TyVar -> RewriteM Reduction
rewriteTyVar :: TcTyVar -> RewriteM Reduction
rewriteTyVar TcTyVar
tv
= do { RewriteTvResult
mb_yes <- TcTyVar -> RewriteM RewriteTvResult
rewrite_tyvar1 TcTyVar
tv
; case RewriteTvResult
mb_yes of
RTRFollowed Reduction
redn -> Reduction -> RewriteM Reduction
rewrite_reduction Reduction
redn
RewriteTvResult
RTRNotFollowed
-> do { TcTyVar
tv' <- forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Monad m =>
(Xi -> m Xi) -> TcTyVar -> m TcTyVar
updateTyVarKindM Xi -> TcS Xi
zonkTcType TcTyVar
tv
; Role
role <- RewriteM Role
getRole
; let ty' :: Xi
ty' = TcTyVar -> Xi
mkTyVarTy TcTyVar
tv'
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Role -> Xi -> Reduction
mkReflRedn Role
role Xi
ty' } }
rewrite_tyvar1 :: TcTyVar -> RewriteM RewriteTvResult
rewrite_tyvar1 :: TcTyVar -> RewriteM RewriteTvResult
rewrite_tyvar1 TcTyVar
tv
= do { Maybe Xi
mb_ty <- forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ TcTyVar -> TcS (Maybe Xi)
isFilledMetaTyVar_maybe TcTyVar
tv
; case Maybe Xi
mb_ty of
Just Xi
ty -> do { String -> SDoc -> RewriteM ()
traceRewriteM String
"Following filled tyvar"
(forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv SDoc -> SDoc -> SDoc
<+> SDoc
equals SDoc -> SDoc -> SDoc
<+> forall a. Outputable a => a -> SDoc
ppr Xi
ty)
; Role
role <- RewriteM Role
getRole
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Reduction -> RewriteTvResult
RTRFollowed forall a b. (a -> b) -> a -> b
$
Role -> Xi -> Reduction
mkReflRedn Role
role Xi
ty }
Maybe Xi
Nothing -> do { String -> SDoc -> RewriteM ()
traceRewriteM String
"Unfilled tyvar" (TcTyVar -> SDoc
pprTyVar TcTyVar
tv)
; CtFlavourRole
fr <- RewriteM CtFlavourRole
getFlavourRole
; TcTyVar -> CtFlavourRole -> RewriteM RewriteTvResult
rewrite_tyvar2 TcTyVar
tv CtFlavourRole
fr } }
rewrite_tyvar2 :: TcTyVar -> CtFlavourRole -> RewriteM RewriteTvResult
rewrite_tyvar2 :: TcTyVar -> CtFlavourRole -> RewriteM RewriteTvResult
rewrite_tyvar2 TcTyVar
tv fr :: CtFlavourRole
fr@(CtFlavour
_, EqRel
eq_rel)
= do { InertEqs
ieqs <- forall a. TcS a -> RewriteM a
liftTcS forall a b. (a -> b) -> a -> b
$ TcS InertEqs
getInertEqs
; case forall a. DVarEnv a -> TcTyVar -> Maybe a
lookupDVarEnv InertEqs
ieqs TcTyVar
tv of
Just [Ct]
equal_ct_list
| Just Ct
ct <- forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find Ct -> Bool
can_rewrite [Ct]
equal_ct_list
, CEqCan { cc_ev :: Ct -> CtEvidence
cc_ev = CtEvidence
ctev, cc_lhs :: Ct -> CanEqLHS
cc_lhs = TyVarLHS TcTyVar
tv
, cc_rhs :: Ct -> Xi
cc_rhs = Xi
rhs_ty, cc_eq_rel :: Ct -> EqRel
cc_eq_rel = EqRel
ct_eq_rel } <- Ct
ct
-> do { let wrw :: Bool
wrw = Ct -> Bool
isWantedCt Ct
ct
; String -> SDoc -> RewriteM ()
traceRewriteM String
"Following inert tyvar" forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat [ forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv SDoc -> SDoc -> SDoc
<+> SDoc
equals SDoc -> SDoc -> SDoc
<+> forall a. Outputable a => a -> SDoc
ppr Xi
rhs_ty
, forall a. Outputable a => a -> SDoc
ppr CtEvidence
ctev
, String -> SDoc
text String
"wanted_rewrite_wanted:" SDoc -> SDoc -> SDoc
<+> forall a. Outputable a => a -> SDoc
ppr Bool
wrw ]
; forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
wrw forall a b. (a -> b) -> a -> b
$ CtEvidence -> RewriteM ()
recordRewriter CtEvidence
ctev
; let rewriting_co1 :: Coercion
rewriting_co1 = HasDebugCallStack => CtEvidence -> Coercion
ctEvCoercion CtEvidence
ctev
rewriting_co :: Coercion
rewriting_co = case (EqRel
ct_eq_rel, EqRel
eq_rel) of
(EqRel
ReprEq, EqRel
_rel) -> forall a. HasCallStack => Bool -> a -> a
assert (EqRel
_rel forall a. Eq a => a -> a -> Bool
== EqRel
ReprEq)
Coercion
rewriting_co1
(EqRel
NomEq, EqRel
NomEq) -> Coercion
rewriting_co1
(EqRel
NomEq, EqRel
ReprEq) -> HasDebugCallStack => Coercion -> Coercion
mkSubCo Coercion
rewriting_co1
; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Reduction -> RewriteTvResult
RTRFollowed forall a b. (a -> b) -> a -> b
$ Coercion -> Xi -> Reduction
mkReduction Coercion
rewriting_co Xi
rhs_ty }
Maybe [Ct]
_other -> forall (m :: * -> *) a. Monad m => a -> m a
return RewriteTvResult
RTRNotFollowed }
where
can_rewrite :: Ct -> Bool
can_rewrite :: Ct -> Bool
can_rewrite Ct
ct = Ct -> CtFlavourRole
ctFlavourRole Ct
ct CtFlavourRole -> CtFlavourRole -> Bool
`eqCanRewriteFR` CtFlavourRole
fr
split_pi_tys' :: Type -> ([TyCoBinder], Type, Bool)
split_pi_tys' :: Xi -> ([TyCoBinder], Xi, Bool)
split_pi_tys' Xi
ty = Xi -> Xi -> ([TyCoBinder], Xi, Bool)
split Xi
ty Xi
ty
where
split :: Xi -> Xi -> ([TyCoBinder], Xi, Bool)
split Xi
_ (ForAllTy TyVarBinder
b Xi
res) = let
!([TyCoBinder]
bs, Xi
ty, Bool
_) = Xi -> Xi -> ([TyCoBinder], Xi, Bool)
split Xi
res Xi
res
in (TyVarBinder -> TyCoBinder
Named TyVarBinder
b forall a. a -> [a] -> [a]
: [TyCoBinder]
bs, Xi
ty, Bool
True)
split Xi
_ (FunTy { ft_af :: Xi -> AnonArgFlag
ft_af = AnonArgFlag
af, ft_mult :: Xi -> Xi
ft_mult = Xi
w, ft_arg :: Xi -> Xi
ft_arg = Xi
arg, ft_res :: Xi -> Xi
ft_res = Xi
res })
= let
!([TyCoBinder]
bs, Xi
ty, Bool
named) = Xi -> Xi -> ([TyCoBinder], Xi, Bool)
split Xi
res Xi
res
in (AnonArgFlag -> Scaled Xi -> TyCoBinder
Anon AnonArgFlag
af (forall a. Xi -> a -> Scaled a
mkScaled Xi
w Xi
arg) forall a. a -> [a] -> [a]
: [TyCoBinder]
bs, Xi
ty, Bool
named)
split Xi
orig_ty Xi
ty | Just Xi
ty' <- Xi -> Maybe Xi
coreView Xi
ty = Xi -> Xi -> ([TyCoBinder], Xi, Bool)
split Xi
orig_ty Xi
ty'
split Xi
orig_ty Xi
_ = ([], Xi
orig_ty, Bool
False)
{-# INLINE split_pi_tys' #-}
ty_con_binders_ty_binders' :: [TyConBinder] -> ([TyCoBinder], Bool)
ty_con_binders_ty_binders' :: [TyConBinder] -> ([TyCoBinder], Bool)
ty_con_binders_ty_binders' = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr TyConBinder -> ([TyCoBinder], Bool) -> ([TyCoBinder], Bool)
go ([], Bool
False)
where
go :: TyConBinder -> ([TyCoBinder], Bool) -> ([TyCoBinder], Bool)
go (Bndr TcTyVar
tv (NamedTCB ArgFlag
vis)) ([TyCoBinder]
bndrs, Bool
_)
= (TyVarBinder -> TyCoBinder
Named (forall var argf. var -> argf -> VarBndr var argf
Bndr TcTyVar
tv ArgFlag
vis) forall a. a -> [a] -> [a]
: [TyCoBinder]
bndrs, Bool
True)
go (Bndr TcTyVar
tv (AnonTCB AnonArgFlag
af)) ([TyCoBinder]
bndrs, Bool
n)
= (AnonArgFlag -> Scaled Xi -> TyCoBinder
Anon AnonArgFlag
af (forall a. a -> Scaled a
tymult (TcTyVar -> Xi
tyVarKind TcTyVar
tv)) forall a. a -> [a] -> [a]
: [TyCoBinder]
bndrs, Bool
n)
{-# INLINE go #-}
{-# INLINE ty_con_binders_ty_binders' #-}