{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveFunctor #-}
module GHC.Tc.Solver.Rewrite(
rewrite, rewriteForErrors, 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 (tYPETyCon)
import Data.List ( find )
import GHC.Data.List.Infinite (Infinite)
import qualified GHC.Data.List.Infinite as Inf
import GHC.Tc.Instance.Family (tcTopNormaliseNewTypeTF_maybe)
newtype RewriteM a
= RewriteM { forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM :: RewriteEnv -> TcS a }
deriving ((forall a b. (a -> b) -> RewriteM a -> RewriteM b)
-> (forall a b. a -> RewriteM b -> RewriteM a) -> Functor RewriteM
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
$cfmap :: forall a b. (a -> b) -> RewriteM a -> RewriteM b
fmap :: forall a b. (a -> b) -> RewriteM a -> RewriteM b
$c<$ :: forall a b. a -> RewriteM b -> RewriteM a
<$ :: forall a b. a -> RewriteM b -> RewriteM a
Functor)
mkRewriteM :: (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM :: forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM RewriteEnv -> TcS a
f = (RewriteEnv -> TcS a) -> RewriteM a
forall a. (RewriteEnv -> TcS a) -> RewriteM a
RewriteM ((RewriteEnv -> TcS a) -> RewriteEnv -> TcS a
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 = (RewriteEnv -> TcS b) -> RewriteM b
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS b) -> RewriteM b)
-> (RewriteEnv -> TcS b) -> RewriteM b
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env ->
do { a
a <- RewriteM a -> RewriteEnv -> TcS a
forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
m RewriteEnv
env
; RewriteM b -> RewriteEnv -> TcS b
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 = (RewriteEnv -> TcS a) -> RewriteM a
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS a) -> RewriteM a)
-> (RewriteEnv -> TcS a) -> RewriteM a
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
_ -> a -> TcS a
forall a. a -> TcS a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
<*> :: forall a b. RewriteM (a -> b) -> RewriteM a -> RewriteM 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 = TcS DynFlags -> RewriteM DynFlags
forall a. TcS a -> RewriteM a
liftTcS TcS DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
liftTcS :: TcS a -> RewriteM a
liftTcS :: forall a. TcS a -> RewriteM a
liftTcS TcS a
thing_inside
= (RewriteEnv -> TcS a) -> RewriteM a
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS a) -> RewriteM a)
-> (RewriteEnv -> TcS a) -> RewriteM a
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
= CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
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 <- RewriterSet -> TcS (TcRef RewriterSet)
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 <- RewriteM a -> RewriteEnv -> TcS a
forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
thing_inside RewriteEnv
fmode
; RewriterSet
rewriters <- TcRef RewriterSet -> TcS RewriterSet
forall a. TcRef a -> TcS a
readTcRef TcRef RewriterSet
rewriters_ref
; (a, RewriterSet) -> TcS (a, RewriterSet)
forall a. a -> TcS a
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 = TcS () -> RewriteM ()
forall a. TcS a -> RewriteM a
liftTcS (TcS () -> RewriteM ()) -> TcS () -> RewriteM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc -> TcS ()
traceTcS String
herald SDoc
doc
{-# INLINE traceRewriteM #-}
getRewriteEnv :: RewriteM RewriteEnv
getRewriteEnv :: RewriteM RewriteEnv
getRewriteEnv
= (RewriteEnv -> TcS RewriteEnv) -> RewriteM RewriteEnv
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS RewriteEnv) -> RewriteM RewriteEnv)
-> (RewriteEnv -> TcS RewriteEnv) -> RewriteM RewriteEnv
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> RewriteEnv -> TcS RewriteEnv
forall a. a -> TcS a
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
= (RewriteEnv -> TcS a) -> RewriteM a
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS a) -> RewriteM a)
-> (RewriteEnv -> TcS a) -> RewriteM a
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> a -> TcS a
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (RewriteEnv -> a
accessor RewriteEnv
env)
getEqRel :: RewriteM EqRel
getEqRel :: RewriteM EqRel
getEqRel = (RewriteEnv -> EqRel) -> RewriteM EqRel
forall a. (RewriteEnv -> a) -> RewriteM a
getRewriteEnvField RewriteEnv -> EqRel
re_eq_rel
getRole :: RewriteM Role
getRole :: RewriteM Role
getRole = EqRel -> Role
eqRelRole (EqRel -> Role) -> RewriteM EqRel -> RewriteM Role
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RewriteM EqRel
getEqRel
getFlavour :: RewriteM CtFlavour
getFlavour :: RewriteM CtFlavour
getFlavour = (RewriteEnv -> CtFlavour) -> RewriteM CtFlavour
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
; CtFlavourRole -> RewriteM CtFlavourRole
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (CtFlavour
flavour, EqRel
eq_rel) }
getLoc :: RewriteM CtLoc
getLoc :: RewriteM CtLoc
getLoc = (RewriteEnv -> CtLoc) -> RewriteM CtLoc
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
; TcS () -> RewriteM ()
forall a. TcS a -> RewriteM a
liftTcS (TcS () -> RewriteM ()) -> TcS () -> RewriteM ()
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
= (RewriteEnv -> TcS a) -> RewriteM a
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS a) -> RewriteM a)
-> (RewriteEnv -> TcS a) -> RewriteM a
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env ->
if EqRel
new_eq_rel EqRel -> EqRel -> Bool
forall a. Eq a => a -> a -> Bool
== RewriteEnv -> EqRel
re_eq_rel RewriteEnv
env
then RewriteM a -> RewriteEnv -> TcS a
forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
thing_inside RewriteEnv
env
else RewriteM a -> RewriteEnv -> TcS a
forall a. RewriteM a -> RewriteEnv -> TcS a
runRewriteM RewriteM a
thing_inside (RewriteEnv
env { re_eq_rel = new_eq_rel })
{-# INLINE setEqRel #-}
bumpDepth :: RewriteM a -> RewriteM a
bumpDepth :: forall a. RewriteM a -> RewriteM a
bumpDepth (RewriteM RewriteEnv -> TcS a
thing_inside)
= (RewriteEnv -> TcS a) -> RewriteM a
forall a. (RewriteEnv -> TcS a) -> RewriteM a
mkRewriteM ((RewriteEnv -> TcS a) -> RewriteM a)
-> (RewriteEnv -> TcS a) -> RewriteM a
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> do
{ let !env' :: RewriteEnv
env' = RewriteEnv
env { re_loc = bumpCtLocDepth (re_loc 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 })
= (RewriteEnv -> TcS ()) -> RewriteM ()
forall a. (RewriteEnv -> TcS a) -> RewriteM a
RewriteM ((RewriteEnv -> TcS ()) -> RewriteM ())
-> (RewriteEnv -> TcS ()) -> RewriteM ()
forall a b. (a -> b) -> a -> b
$ \RewriteEnv
env -> TcRef RewriterSet -> (RewriterSet -> RewriterSet) -> TcS ()
forall a. TcRef a -> (a -> a) -> TcS ()
updTcRef (RewriteEnv -> TcRef RewriterSet
re_rewriters RewriteEnv
env) (RewriterSet -> CoercionHole -> RewriterSet
`addRewriterSet` CoercionHole
hole)
recordRewriter CtEvidence
other = String -> SDoc -> RewriteM ()
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"recordRewriter" (CtEvidence -> SDoc
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 {" (Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr Xi
ty)
; result :: (Reduction, RewriterSet)
result@(Reduction
redn, RewriterSet
_) <- CtEvidence -> RewriteM Reduction -> TcS (Reduction, 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 }" (Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Xi -> SDoc) -> Xi -> SDoc
forall a b. (a -> b) -> a -> b
$ Reduction -> Xi
reductionReducedType Reduction
redn)
; (Reduction, RewriterSet) -> TcS (Reduction, RewriterSet)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction, RewriterSet)
result }
rewriteForErrors :: CtEvidence -> TcType
-> TcS (Reduction, RewriterSet)
rewriteForErrors :: CtEvidence -> Xi -> TcS (Reduction, RewriterSet)
rewriteForErrors CtEvidence
ev Xi
ty
= do { String -> SDoc -> TcS ()
traceTcS String
"rewriteForErrors {" (Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr Xi
ty)
; result :: (Reduction, RewriterSet)
result@(Reduction
redn, RewriterSet
rewriters) <-
CtLoc
-> CtFlavour
-> EqRel
-> RewriteM Reduction
-> TcS (Reduction, RewriterSet)
forall a.
CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
runRewrite (CtEvidence -> CtLoc
ctEvLoc CtEvidence
ev) (CtEvidence -> CtFlavour
ctEvFlavour CtEvidence
ev) EqRel
NomEq (Xi -> RewriteM Reduction
rewrite_one Xi
ty)
; String -> SDoc -> TcS ()
traceTcS String
"rewriteForErrors }" (Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Xi -> SDoc) -> Xi -> SDoc
forall a b. (a -> b) -> a -> b
$ Reduction -> Xi
reductionReducedType Reduction
redn)
; (Reduction, RewriterSet) -> TcS (Reduction, RewriterSet)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Reduction, RewriterSet) -> TcS (Reduction, RewriterSet))
-> (Reduction, RewriterSet) -> TcS (Reduction, RewriterSet)
forall a b. (a -> b) -> a -> b
$ case CtEvidence -> EqRel
ctEvEqRel CtEvidence
ev of
EqRel
NomEq -> (Reduction, RewriterSet)
result
EqRel
ReprEq -> (Reduction -> Reduction
mkSubRedn Reduction
redn, RewriterSet
rewriters) }
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
forall doc. IsDoc doc => [doc] -> doc
vcat ((Xi -> SDoc) -> [Xi] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Xi]
tys))
; (ArgsReductions redns :: Reductions
redns@(Reductions [Coercion]
_ [Xi]
tys') MCoercionN
kind_co, RewriterSet
rewriters)
<- CtEvidence
-> RewriteM ArgsReductions -> TcS (ArgsReductions, RewriterSet)
forall a. CtEvidence -> RewriteM a -> TcS (a, RewriterSet)
runRewriteCtEv CtEvidence
ev (TyCon -> Maybe (Infinite Role) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc Maybe (Infinite Role)
forall a. Maybe a
Nothing [Xi]
tys)
; Bool -> TcS ()
forall (m :: * -> *). (HasCallStack, Applicative m) => Bool -> m ()
massert (MCoercionN -> Bool
isReflMCo MCoercionN
kind_co)
; String -> SDoc -> TcS ()
traceTcS String
"rewrite }" ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ((Xi -> SDoc) -> [Xi] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Xi]
tys'))
; (Reductions, RewriterSet) -> TcS (Reductions, RewriterSet)
forall a. a -> TcS a
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
_) <- CtLoc
-> CtFlavour
-> EqRel
-> RewriteM Reduction
-> TcS (Reduction, RewriterSet)
forall a.
CtLoc -> CtFlavour -> EqRel -> RewriteM a -> TcS (a, RewriterSet)
runRewrite CtLoc
loc CtFlavour
Given EqRel
NomEq (RewriteM Reduction -> TcS (Reduction, RewriterSet))
-> RewriteM Reduction -> TcS (Reduction, RewriterSet)
forall a b. (a -> b) -> a -> b
$
Xi -> RewriteM Reduction
rewrite_one Xi
ty
; Xi -> TcS Xi
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Xi -> TcS Xi) -> Xi -> TcS Xi
forall a b. (a -> b) -> a -> b
$ Reduction -> Xi
reductionReducedType Reduction
redn }
{-# INLINE rewrite_args_tc #-}
rewrite_args_tc
:: TyCon
-> Maybe (Infinite Role)
-> [Type]
-> RewriteM ArgsReductions
rewrite_args_tc :: TyCon -> Maybe (Infinite Role) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc = [PiTyBinder]
-> Bool
-> Xi
-> TcTyCoVarSet
-> Maybe (Infinite Role)
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args [PiTyBinder]
all_bndrs Bool
any_named_bndrs Xi
inner_ki TcTyCoVarSet
emptyVarSet
where
([PiTyBinder]
bndrs, Bool
named)
= [TyConBinder] -> ([PiTyBinder], Bool)
ty_con_binders_ty_binders' (TyCon -> [TyConBinder]
tyConBinders TyCon
tc)
([PiTyBinder]
inner_bndrs, Xi
inner_ki, Bool
inner_named) = Xi -> ([PiTyBinder], Xi, Bool)
split_pi_tys' (TyCon -> Xi
tyConResKind TyCon
tc)
!all_bndrs :: [PiTyBinder]
all_bndrs = [PiTyBinder]
bndrs [PiTyBinder] -> [PiTyBinder] -> [PiTyBinder]
forall a. [a] -> [a] -> [a]
`chkAppend` [PiTyBinder]
inner_bndrs
!any_named_bndrs :: Bool
any_named_bndrs = Bool
named Bool -> Bool -> Bool
|| Bool
inner_named
{-# INLINE rewrite_args #-}
rewrite_args :: [PiTyBinder] -> Bool
-> Kind -> TcTyCoVarSet
-> Maybe (Infinite Role) -> [Type]
-> RewriteM ArgsReductions
rewrite_args :: [PiTyBinder]
-> Bool
-> Xi
-> TcTyCoVarSet
-> Maybe (Infinite Role)
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args [PiTyBinder]
orig_binders
Bool
any_named_bndrs
Xi
orig_inner_ki
TcTyCoVarSet
orig_fvs
Maybe (Infinite Role)
orig_m_roles
[Xi]
orig_tys
= case (Maybe (Infinite Role)
orig_m_roles, Bool
any_named_bndrs) of
(Maybe (Infinite Role)
Nothing, Bool
False) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_fast [Xi]
orig_tys
(Maybe (Infinite Role), Bool)
_ -> [PiTyBinder]
-> Xi
-> TcTyCoVarSet
-> Infinite Role
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args_slow [PiTyBinder]
orig_binders Xi
orig_inner_ki TcTyCoVarSet
orig_fvs Infinite Role
orig_roles [Xi]
orig_tys
where orig_roles :: Infinite Role
orig_roles = Infinite Role -> Maybe (Infinite Role) -> Infinite Role
forall a. a -> Maybe a -> a
fromMaybe (Role -> Infinite Role
forall a. a -> Infinite a
Inf.repeat Role
Nominal) Maybe (Infinite 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
= (Reductions -> ArgsReductions)
-> RewriteM Reductions -> RewriteM ArgsReductions
forall a b. (a -> b) -> RewriteM a -> RewriteM b
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
Reductions -> RewriteM Reductions
forall a. a -> RewriteM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Reductions -> RewriteM Reductions)
-> Reductions -> RewriteM Reductions
forall a b. (a -> b) -> a -> b
$ [Coercion] -> [Xi] -> Reductions
Reductions (Coercion
co Coercion -> [Coercion] -> [Coercion]
forall a. a -> [a] -> [a]
: [Coercion]
cos) (Xi
xi Xi -> [Xi] -> [Xi]
forall a. a -> [a] -> [a]
: [Xi]
xis)
iterate [] = Reductions -> RewriteM Reductions
forall a. a -> RewriteM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Reductions -> RewriteM Reductions)
-> Reductions -> RewriteM Reductions
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 :: [PiTyBinder] -> Kind -> TcTyCoVarSet
-> Infinite Role -> [Type]
-> RewriteM ArgsReductions
rewrite_args_slow :: [PiTyBinder]
-> Xi
-> TcTyCoVarSet
-> Infinite Role
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args_slow [PiTyBinder]
binders Xi
inner_ki TcTyCoVarSet
fvs Infinite Role
roles [Xi]
tys
= do { [Reduction]
rewritten_args <- (Role -> Xi -> RewriteM Reduction)
-> [Role] -> [Xi] -> RewriteM [Reduction]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM Role -> Xi -> RewriteM Reduction
rw (Infinite Role -> [Role]
forall a. Infinite a -> [a]
Inf.toList Infinite Role
roles) [Xi]
tys
; ArgsReductions -> RewriteM ArgsReductions
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([PiTyBinder]
-> Xi
-> TcTyCoVarSet
-> Infinite Role
-> [Reduction]
-> ArgsReductions
(() :: Constraint) =>
[PiTyBinder]
-> Xi
-> TcTyCoVarSet
-> Infinite Role
-> [Reduction]
-> ArgsReductions
simplifyArgsWorker [PiTyBinder]
binders Xi
inner_ki TcTyCoVarSet
fvs Infinite Role
roles [Reduction]
rewritten_args) }
where
{-# INLINE rw #-}
rw :: Role -> Type -> RewriteM Reduction
rw :: Role -> Xi -> RewriteM Reduction
rw Role
Nominal Xi
ty
= EqRel -> RewriteM Reduction -> RewriteM Reduction
forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
NomEq (RewriteM Reduction -> RewriteM Reduction)
-> RewriteM Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$
Xi -> RewriteM Reduction
rewrite_one Xi
ty
rw Role
Representational Xi
ty
= EqRel -> RewriteM Reduction -> RewriteM Reduction
forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
ReprEq (RewriteM Reduction -> RewriteM Reduction)
-> RewriteM Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$
Xi -> RewriteM Reduction
rewrite_one Xi
ty
rw Role
Phantom Xi
ty
= do { Xi
ty <- TcS Xi -> RewriteM Xi
forall a. TcS a -> RewriteM a
liftTcS (TcS Xi -> RewriteM Xi) -> TcS Xi -> RewriteM Xi
forall a b. (a -> b) -> a -> b
$ Xi -> TcS Xi
zonkTcType Xi
ty
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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 ty :: Xi
ty@(TyConApp TyCon
tc [Xi]
tys)
| TyCon -> Bool
isTypeFamilyTyCon TyCon
tc
= TyCon -> [Xi] -> RewriteM Reduction
rewrite_fam_app TyCon
tc [Xi]
tys
| Bool
otherwise
= do { EqRel
eq_rel <- RewriteM EqRel
getEqRel
; if EqRel
eq_rel EqRel -> EqRel -> Bool
forall a. Eq a => a -> a -> Bool
== EqRel
ReprEq
then
Xi -> RewriteM Reduction
rewrite_newtype_app Xi
ty
else
TyCon -> [Xi] -> RewriteM Reduction
rewrite_ty_con_app TyCon
tc [Xi]
tys }
rewrite_one (FunTy { ft_af :: Xi -> FunTyFlag
ft_af = FunTyFlag
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 = (() :: Constraint) => Xi -> Xi
Xi -> Xi
getRuntimeRep (Reduction -> Xi
reductionReducedType Reduction
arg_redn)
res_rep :: Xi
res_rep = (() :: Constraint) => Xi -> Xi
Xi -> Xi
getRuntimeRep (Reduction -> Xi
reductionReducedType Reduction
res_redn)
; (Reduction
w_redn, Reduction
arg_rep_redn, Reduction
res_rep_redn) <- EqRel
-> RewriteM (Reduction, Reduction, Reduction)
-> RewriteM (Reduction, Reduction, Reduction)
forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
NomEq (RewriteM (Reduction, Reduction, Reduction)
-> RewriteM (Reduction, Reduction, Reduction))
-> RewriteM (Reduction, Reduction, Reduction)
-> RewriteM (Reduction, Reduction, Reduction)
forall a b. (a -> b) -> a -> b
$
(Reduction
-> Reduction -> Reduction -> (Reduction, Reduction, Reduction))
-> RewriteM Reduction
-> RewriteM Reduction
-> RewriteM Reduction
-> RewriteM (Reduction, Reduction, Reduction)
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 = (() :: Constraint) => Role -> TyCon -> [Coercion] -> Coercion
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 = (() :: Constraint) => Role -> TyCon -> [Coercion] -> Coercion
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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$ Role
-> FunTyFlag -> Reduction -> Reduction -> Reduction -> Reduction
mkFunRedn Role
role FunTyFlag
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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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 = TcS Coercion -> RewriteM Coercion
forall a. TcS a -> RewriteM a
liftTcS (TcS Coercion -> RewriteM Coercion)
-> TcS Coercion -> RewriteM Coercion
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 <- RewriteM Reduction -> RewriteM Reduction
forall a. RewriteM a -> RewriteM a
bumpDepth (RewriteM Reduction -> RewriteM Reduction)
-> RewriteM Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$ Xi -> RewriteM Reduction
rewrite_one Xi
xi
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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
ty2Xi -> [Xi] -> [Xi]
forall 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 []
= Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
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])
Xi -> Maybe (TyCon, [Xi])
tcSplitTyConApp_maybe Xi
fun_xi of
Just (TyCon
tc, [Xi]
xis) ->
do { let tc_roles :: Infinite Role
tc_roles = TyCon -> Infinite Role
tyConRolesRepresentational TyCon
tc
arg_roles :: Infinite Role
arg_roles = [Xi] -> Infinite Role -> Infinite Role
forall a b. [a] -> Infinite b -> Infinite b
Inf.dropList [Xi]
xis Infinite Role
tc_roles
; ArgsReductions (Reductions [Coercion]
arg_cos [Xi]
arg_xis) MCoercionN
kind_co
<- Xi -> Infinite Role -> [Xi] -> RewriteM ArgsReductions
rewrite_vector ((() :: Constraint) => Xi -> Xi
Xi -> Xi
typeKind Xi
fun_xi) Infinite 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 [Xi] -> [Xi] -> [Xi]
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 ((Xi -> Coercion) -> [Xi] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Xi -> Coercion
mkNomReflCo [Xi]
arg_tys)
Coercion -> Coercion -> Coercion
`mkTransCo`
(() :: Constraint) => Role -> TyCon -> [Coercion] -> Coercion
Role -> TyCon -> [Coercion] -> Coercion
mkTyConAppCo Role
Representational TyCon
tc
((Role -> Xi -> Coercion) -> [Role] -> [Xi] -> [Coercion]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Role -> Xi -> Coercion
mkReflCo (Infinite Role -> [Role]
forall a. Infinite a -> [a]
Inf.toList Infinite Role
tc_roles) [Xi]
xis [Coercion] -> [Coercion] -> [Coercion]
forall a. [a] -> [a] -> [a]
++ [Coercion]
arg_cos)
; HetReduction -> RewriteM HetReduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (HetReduction -> RewriteM HetReduction)
-> HetReduction -> RewriteM HetReduction
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 -> Infinite Role -> [Xi] -> RewriteM ArgsReductions
rewrite_vector ((() :: Constraint) => Xi -> Xi
Xi -> Xi
typeKind Xi
fun_xi) (Role -> Infinite Role
forall a. a -> Infinite a
Inf.repeat Role
Nominal) [Xi]
arg_tys
; HetReduction -> RewriteM HetReduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (HetReduction -> RewriteM HetReduction)
-> HetReduction -> RewriteM HetReduction
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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
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 (Infinite Role)
m_roles | Role
Nominal <- Role
role = Maybe (Infinite Role)
forall a. Maybe a
Nothing
| Bool
otherwise = Infinite Role -> Maybe (Infinite Role)
forall a. a -> Maybe a
Just (Infinite Role -> Maybe (Infinite Role))
-> Infinite Role -> Maybe (Infinite Role)
forall a b. (a -> b) -> a -> b
$ Role -> TyCon -> Infinite Role
tyConRolesX Role
role TyCon
tc
; ArgsReductions Reductions
redns MCoercionN
kind_co <- TyCon -> Maybe (Infinite Role) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc Maybe (Infinite 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
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$ Role -> HetReduction -> Reduction
homogeniseHetRedn Role
role HetReduction
tyconapp_redn }
rewrite_vector :: Kind
-> Infinite Role
-> [Type]
-> RewriteM ArgsReductions
rewrite_vector :: Xi -> Infinite Role -> [Xi] -> RewriteM ArgsReductions
rewrite_vector Xi
ki Infinite Role
roles [Xi]
tys
= do { EqRel
eq_rel <- RewriteM EqRel
getEqRel
; let mb_roles :: Maybe (Infinite Role)
mb_roles = case EqRel
eq_rel of { EqRel
NomEq -> Maybe (Infinite Role)
forall a. Maybe a
Nothing; EqRel
ReprEq -> Infinite Role -> Maybe (Infinite Role)
forall a. a -> Maybe a
Just Infinite Role
roles }
; [PiTyBinder]
-> Bool
-> Xi
-> TcTyCoVarSet
-> Maybe (Infinite Role)
-> [Xi]
-> RewriteM ArgsReductions
rewrite_args [PiTyBinder]
bndrs Bool
any_named_bndrs Xi
inner_ki TcTyCoVarSet
fvs Maybe (Infinite Role)
mb_roles [Xi]
tys
}
where
([PiTyBinder]
bndrs, Xi
inner_ki, Bool
any_named_bndrs) = Xi -> ([PiTyBinder], Xi, Bool)
split_pi_tys' Xi
ki
fvs :: TcTyCoVarSet
fvs = Xi -> TcTyCoVarSet
tyCoVarsOfType Xi
ki
{-# INLINE rewrite_vector #-}
rewrite_newtype_app :: TcType -> RewriteM Reduction
rewrite_newtype_app :: Xi -> RewriteM Reduction
rewrite_newtype_app ty :: Xi
ty@(TyConApp TyCon
tc [Xi]
tys)
= do { GlobalRdrEnv
rdr_env <- TcS GlobalRdrEnv -> RewriteM GlobalRdrEnv
forall a. TcS a -> RewriteM a
liftTcS TcS GlobalRdrEnv
getGlobalRdrEnvTcS
; (FamInstEnv, FamInstEnv)
tf_envs <- TcS (FamInstEnv, FamInstEnv) -> RewriteM (FamInstEnv, FamInstEnv)
forall a. TcS a -> RewriteM a
liftTcS TcS (FamInstEnv, FamInstEnv)
getFamInstEnvs
; case ((FamInstEnv, FamInstEnv)
-> GlobalRdrEnv -> Xi -> Maybe ((Bag GlobalRdrElt, Coercion), Xi)
tcTopNormaliseNewTypeTF_maybe (FamInstEnv, FamInstEnv)
tf_envs GlobalRdrEnv
rdr_env Xi
ty) of
Maybe ((Bag GlobalRdrElt, Coercion), Xi)
Nothing ->
TyCon -> [Xi] -> RewriteM Reduction
rewrite_ty_con_app TyCon
tc [Xi]
tys
Just ((Bag GlobalRdrElt
used_ctors, Coercion
co), Xi
ty')
-> do { TcS () -> RewriteM ()
forall a. TcS a -> RewriteM a
liftTcS (TcS () -> RewriteM ()) -> TcS () -> RewriteM ()
forall a b. (a -> b) -> a -> b
$ Bag GlobalRdrElt -> TcS ()
recordUsedGREs Bag GlobalRdrElt
used_ctors
; Xi -> RewriteM ()
checkStackDepth Xi
ty
; Reduction -> RewriteM Reduction
rewrite_reduction (Coercion -> Xi -> Reduction
Reduction Coercion
co Xi
ty') } }
rewrite_newtype_app Xi
other_ty = String -> SDoc -> RewriteM Reduction
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"rewrite_newtype_app" (Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr Xi
other_ty)
rewrite_fam_app :: TyCon -> [TcType] -> RewriteM Reduction
rewrite_fam_app :: TyCon -> [Xi] -> RewriteM Reduction
rewrite_fam_app TyCon
tc [Xi]
tys
= Bool -> SDoc -> RewriteM Reduction -> RewriteM Reduction
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr ([Xi]
tys [Xi] -> Arity -> Bool
forall a. [a] -> Arity -> Bool
`lengthAtLeast` TyCon -> Arity
tyConArity TyCon
tc)
(TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Arity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (TyCon -> Arity
tyConArity TyCon
tc) SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ [Xi] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Xi]
tys) (RewriteM Reduction -> RewriteM Reduction)
-> RewriteM Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$
do { let ([Xi]
tys1, [Xi]
tys_rest) = Arity -> [Xi] -> ([Xi], [Xi])
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 EqRel -> EqRel -> Bool
forall a. Eq a => a -> a -> Bool
== EqRel
NomEq
then TyCon -> Maybe (Infinite Role) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc Maybe (Infinite Role)
forall a. Maybe a
Nothing [Xi]
tys
else EqRel -> RewriteM ArgsReductions -> RewriteM ArgsReductions
forall a. EqRel -> RewriteM a -> RewriteM a
setEqRel EqRel
NomEq (RewriteM ArgsReductions -> RewriteM ArgsReductions)
-> RewriteM ArgsReductions -> RewriteM ArgsReductions
forall a b. (a -> b) -> a -> b
$
TyCon -> Maybe (Infinite Role) -> [Xi] -> RewriteM ArgsReductions
rewrite_args_tc TyCon
tc Maybe (Infinite Role)
forall a. Maybe a
Nothing [Xi]
tys
; let
role :: Role
role = EqRel -> Role
eqRelRole EqRel
eq_rel
args_co :: Coercion
args_co = (() :: Constraint) => Role -> TyCon -> [Coercion] -> Coercion
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
(HetReduction -> Reduction) -> HetReduction -> Reduction
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 (Reduction -> Reduction) -> Reduction -> Reduction
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 <- TcS (Maybe (Reduction, CtFlavourRole))
-> RewriteM (Maybe (Reduction, CtFlavourRole))
forall a. TcS a -> RewriteM a
liftTcS (TcS (Maybe (Reduction, CtFlavourRole))
-> RewriteM (Maybe (Reduction, CtFlavourRole)))
-> TcS (Maybe (Reduction, CtFlavourRole))
-> RewriteM (Maybe (Reduction, CtFlavourRole))
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"
(TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Xi] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Xi]
xis SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Reduction -> SDoc
forall a. Outputable a => a -> SDoc
ppr Reduction
redn)
; Bool -> Reduction -> RewriteM Reduction
finish (CtFlavour
inert_flavour CtFlavour -> CtFlavour -> Bool
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
_ -> Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
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
; Bool -> RewriteM () -> RewriteM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
use_cache Bool -> Bool -> Bool
&& EqRel
eq_rel EqRel -> EqRel -> Bool
forall a. Eq a => a -> a -> Bool
== EqRel
NomEq) (RewriteM () -> RewriteM ()) -> RewriteM () -> RewriteM ()
forall a b. (a -> b) -> a -> b
$
TcS () -> RewriteM ()
forall a. TcS a -> RewriteM a
liftTcS (TcS () -> RewriteM ()) -> TcS () -> RewriteM ()
forall a b. (a -> b) -> a -> b
$ TyCon -> [Xi] -> Reduction -> TcS ()
extendFamAppCache TyCon
tc [Xi]
tys Reduction
final_redn
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
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 <-
TcS (Maybe Reduction) -> RewriteM (Maybe Reduction)
forall a. TcS a -> RewriteM a
liftTcS (TcS (Maybe Reduction) -> RewriteM (Maybe Reduction))
-> TcS (Maybe Reduction) -> RewriteM (Maybe Reduction)
forall a b. (a -> b) -> a -> b
$ [TcS (Maybe Reduction)] -> TcS (Maybe Reduction)
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 ]
; (Reduction -> RewriteM Reduction)
-> Maybe Reduction -> RewriteM (Maybe Reduction)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Maybe a -> f (Maybe 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" (SDoc -> RewriteM ()) -> SDoc -> RewriteM ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc
, [Xi] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Xi]
tys
, Reduction -> SDoc
forall a. Outputable a => a -> SDoc
ppr Reduction
redn
]
; EqRel
eq_rel <- RewriteM EqRel
getEqRel
; case EqRel
eq_rel of
EqRel
NomEq -> Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return Reduction
redn
EqRel
ReprEq -> Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
forall a b. (a -> b) -> a -> b
$ Reduction -> Reduction
mkSubRedn Reduction
redn }
getTcPluginRewritersForTyCon :: TyCon -> RewriteM [TcPluginRewriter]
getTcPluginRewritersForTyCon :: TyCon -> RewriteM [TcPluginRewriter]
getTcPluginRewritersForTyCon TyCon
tc
= TcS [TcPluginRewriter] -> RewriteM [TcPluginRewriter]
forall a. TcS a -> RewriteM a
liftTcS (TcS [TcPluginRewriter] -> RewriteM [TcPluginRewriter])
-> TcS [TcPluginRewriter] -> RewriteM [TcPluginRewriter]
forall a b. (a -> b) -> a -> b
$ do { UniqFM TyCon [TcPluginRewriter]
rewriters <- TcGblEnv -> UniqFM TyCon [TcPluginRewriter]
tcg_tc_plugin_rewriters (TcGblEnv -> UniqFM TyCon [TcPluginRewriter])
-> TcS TcGblEnv -> TcS (UniqFM TyCon [TcPluginRewriter])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TcS TcGblEnv
getGblEnv
; [TcPluginRewriter] -> TcS [TcPluginRewriter]
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (UniqFM TyCon [TcPluginRewriter]
-> [TcPluginRewriter] -> TyCon -> [TcPluginRewriter]
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
| [TcPluginRewriter] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TcPluginRewriter]
rewriterFunctions
= Maybe Reduction -> TcS (Maybe Reduction)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Reduction
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]
_ []
= Maybe Reduction -> TcS (Maybe Reduction)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Reduction
forall a. Maybe a
Nothing
runRewriters [Ct]
givens (TcPluginRewriter
rewriter:[TcPluginRewriter]
rewriters)
= do
TcPluginRewriteResult
rewriteResult <- TcM TcPluginRewriteResult -> TcS TcPluginRewriteResult
forall a. TcM a -> TcS a
wrapTcS (TcM TcPluginRewriteResult -> TcS TcPluginRewriteResult)
-> (TcPluginM TcPluginRewriteResult -> TcM TcPluginRewriteResult)
-> TcPluginM TcPluginRewriteResult
-> TcS TcPluginRewriteResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcPluginM TcPluginRewriteResult -> TcM TcPluginRewriteResult
forall a. TcPluginM a -> TcM a
runTcPluginM (TcPluginM TcPluginRewriteResult -> TcS TcPluginRewriteResult)
-> TcPluginM TcPluginRewriteResult -> TcS TcPluginRewriteResult
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; Maybe Reduction -> TcS (Maybe Reduction)
forall a. a -> TcS a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Reduction -> TcS (Maybe Reduction))
-> Maybe Reduction -> TcS (Maybe Reduction)
forall a b. (a -> b) -> a -> b
$ Reduction -> Maybe Reduction
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' <- TcS TcTyVar -> RewriteM TcTyVar
forall a. TcS a -> RewriteM a
liftTcS (TcS TcTyVar -> RewriteM TcTyVar)
-> TcS TcTyVar -> RewriteM TcTyVar
forall a b. (a -> b) -> a -> b
$ (Xi -> TcS Xi) -> TcTyVar -> TcS TcTyVar
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'
; Reduction -> RewriteM Reduction
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduction -> RewriteM Reduction)
-> Reduction -> RewriteM Reduction
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 <- TcS (Maybe Xi) -> RewriteM (Maybe Xi)
forall a. TcS a -> RewriteM a
liftTcS (TcS (Maybe Xi) -> RewriteM (Maybe Xi))
-> TcS (Maybe Xi) -> RewriteM (Maybe Xi)
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"
(TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr Xi
ty)
; Role
role <- RewriteM Role
getRole
; RewriteTvResult -> RewriteM RewriteTvResult
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (RewriteTvResult -> RewriteM RewriteTvResult)
-> RewriteTvResult -> RewriteM RewriteTvResult
forall a b. (a -> b) -> a -> b
$ Reduction -> RewriteTvResult
RTRFollowed (Reduction -> RewriteTvResult) -> Reduction -> RewriteTvResult
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 <- TcS InertEqs -> RewriteM InertEqs
forall a. TcS a -> RewriteM a
liftTcS (TcS InertEqs -> RewriteM InertEqs)
-> TcS InertEqs -> RewriteM InertEqs
forall a b. (a -> b) -> a -> b
$ TcS InertEqs
getInertEqs
; case InertEqs -> TcTyVar -> Maybe [Ct]
forall a. DVarEnv a -> TcTyVar -> Maybe a
lookupDVarEnv InertEqs
ieqs TcTyVar
tv of
Just [Ct]
equal_ct_list
| Just Ct
ct <- (Ct -> Bool) -> [Ct] -> Maybe 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" (SDoc -> RewriteM ()) -> SDoc -> RewriteM ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ TcTyVar -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcTyVar
tv SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Xi -> SDoc
forall a. Outputable a => a -> SDoc
ppr Xi
rhs_ty
, CtEvidence -> SDoc
forall a. Outputable a => a -> SDoc
ppr CtEvidence
ctev
, String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"wanted_rewrite_wanted:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
wrw ]
; Bool -> RewriteM () -> RewriteM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
wrw (RewriteM () -> RewriteM ()) -> RewriteM () -> RewriteM ()
forall a b. (a -> b) -> a -> b
$ CtEvidence -> RewriteM ()
recordRewriter CtEvidence
ctev
; let rewriting_co1 :: Coercion
rewriting_co1 = (() :: Constraint) => CtEvidence -> Coercion
CtEvidence -> Coercion
ctEvCoercion CtEvidence
ctev
rewriting_co :: Coercion
rewriting_co = case (EqRel
ct_eq_rel, EqRel
eq_rel) of
(EqRel
ReprEq, EqRel
_rel) -> Bool -> Coercion -> Coercion
forall a. HasCallStack => Bool -> a -> a
assert (EqRel
_rel EqRel -> EqRel -> Bool
forall a. Eq a => a -> a -> Bool
== EqRel
ReprEq)
Coercion
rewriting_co1
(EqRel
NomEq, EqRel
NomEq) -> Coercion
rewriting_co1
(EqRel
NomEq, EqRel
ReprEq) -> (() :: Constraint) => Coercion -> Coercion
Coercion -> Coercion
mkSubCo Coercion
rewriting_co1
; RewriteTvResult -> RewriteM RewriteTvResult
forall a. a -> RewriteM a
forall (m :: * -> *) a. Monad m => a -> m a
return (RewriteTvResult -> RewriteM RewriteTvResult)
-> RewriteTvResult -> RewriteM RewriteTvResult
forall a b. (a -> b) -> a -> b
$ Reduction -> RewriteTvResult
RTRFollowed (Reduction -> RewriteTvResult) -> Reduction -> RewriteTvResult
forall a b. (a -> b) -> a -> b
$ Coercion -> Xi -> Reduction
mkReduction Coercion
rewriting_co Xi
rhs_ty }
Maybe [Ct]
_other -> RewriteTvResult -> RewriteM RewriteTvResult
forall a. a -> RewriteM a
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 -> ([PiTyBinder], Type, Bool)
split_pi_tys' :: Xi -> ([PiTyBinder], Xi, Bool)
split_pi_tys' Xi
ty = Xi -> Xi -> ([PiTyBinder], Xi, Bool)
split Xi
ty Xi
ty
where
split :: Xi -> Xi -> ([PiTyBinder], Xi, Bool)
split Xi
_ (ForAllTy TyVarBinder
b Xi
res) = let
!([PiTyBinder]
bs, Xi
ty, Bool
_) = Xi -> Xi -> ([PiTyBinder], Xi, Bool)
split Xi
res Xi
res
in (TyVarBinder -> PiTyBinder
Named TyVarBinder
b PiTyBinder -> [PiTyBinder] -> [PiTyBinder]
forall a. a -> [a] -> [a]
: [PiTyBinder]
bs, Xi
ty, Bool
True)
split Xi
_ (FunTy { ft_af :: Xi -> FunTyFlag
ft_af = FunTyFlag
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
!([PiTyBinder]
bs, Xi
ty, Bool
named) = Xi -> Xi -> ([PiTyBinder], Xi, Bool)
split Xi
res Xi
res
in (Scaled Xi -> FunTyFlag -> PiTyBinder
Anon (Xi -> Xi -> Scaled Xi
forall a. Xi -> a -> Scaled a
mkScaled Xi
w Xi
arg) FunTyFlag
af PiTyBinder -> [PiTyBinder] -> [PiTyBinder]
forall a. a -> [a] -> [a]
: [PiTyBinder]
bs, Xi
ty, Bool
named)
split Xi
orig_ty Xi
ty | Just Xi
ty' <- Xi -> Maybe Xi
coreView Xi
ty = Xi -> Xi -> ([PiTyBinder], 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] -> ([PiTyBinder], Bool)
ty_con_binders_ty_binders' :: [TyConBinder] -> ([PiTyBinder], Bool)
ty_con_binders_ty_binders' = (TyConBinder -> ([PiTyBinder], Bool) -> ([PiTyBinder], Bool))
-> ([PiTyBinder], Bool) -> [TyConBinder] -> ([PiTyBinder], Bool)
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr TyConBinder -> ([PiTyBinder], Bool) -> ([PiTyBinder], Bool)
go ([], Bool
False)
where
go :: TyConBinder -> ([PiTyBinder], Bool) -> ([PiTyBinder], Bool)
go (Bndr TcTyVar
tv (NamedTCB ForAllTyFlag
vis)) ([PiTyBinder]
bndrs, Bool
_)
= (TyVarBinder -> PiTyBinder
Named (TcTyVar -> ForAllTyFlag -> TyVarBinder
forall var argf. var -> argf -> VarBndr var argf
Bndr TcTyVar
tv ForAllTyFlag
vis) PiTyBinder -> [PiTyBinder] -> [PiTyBinder]
forall a. a -> [a] -> [a]
: [PiTyBinder]
bndrs, Bool
True)
go (Bndr TcTyVar
tv (AnonTCB FunTyFlag
af)) ([PiTyBinder]
bndrs, Bool
n)
= (Scaled Xi -> FunTyFlag -> PiTyBinder
Anon (Xi -> Scaled Xi
forall a. a -> Scaled a
tymult (TcTyVar -> Xi
tyVarKind TcTyVar
tv)) FunTyFlag
af PiTyBinder -> [PiTyBinder] -> [PiTyBinder]
forall a. a -> [a] -> [a]
: [PiTyBinder]
bndrs, Bool
n)
{-# INLINE go #-}
{-# INLINE ty_con_binders_ty_binders' #-}