{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE TypeSynonymInstances      #-}
{-# LANGUAGE FlexibleInstances         #-}
{-# LANGUAGE FlexibleContexts          #-}
{-# LANGUAGE TupleSections             #-}
{-# LANGUAGE DeriveDataTypeable        #-}
{-# LANGUAGE ScopedTypeVariables       #-}


module Language.Haskell.Liquid.Types.Visitors (
  
  CBVisitable (..)
  
  -- * visitors
  , coreVisitor 
  , CoreVisitor (..)

  ) where

import           CoreSyn
import           Data.Hashable
import           DataCon

import           Data.List                        (foldl', (\\), delete)
import qualified Data.HashSet                     as S
import           Prelude                          hiding (error)
import           Language.Fixpoint.Misc
import           Language.Haskell.Liquid.GHC.API
import           Language.Haskell.Liquid.GHC.Misc ()


------------------------------------------------------------------------------
-------------------------------- A CoreBind Visitor --------------------------
------------------------------------------------------------------------------

-- TODO: syb-shrinkage

class CBVisitable a where
  freeVars :: S.HashSet Var -> a -> [Var]
  readVars :: a -> [Var]
  letVars  :: a -> [Var]
  literals :: a -> [Literal]

instance CBVisitable [CoreBind] where
  freeVars :: HashSet Var -> [CoreBind] -> [Var]
freeVars HashSet Var
env [CoreBind]
cbs = ([Var] -> [Var]
forall a. Ord a => [a] -> [a]
sortNub [Var]
xs) [Var] -> [Var] -> [Var]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Var]
ys
    where xs :: [Var]
xs = (CoreBind -> [Var]) -> [CoreBind] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (HashSet Var -> CoreBind -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars HashSet Var
env) [CoreBind]
cbs
          ys :: [Var]
ys = (CoreBind -> [Var]) -> [CoreBind] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CoreBind -> [Var]
forall t. Bind t -> [t]
bindings [CoreBind]
cbs

  readVars :: [CoreBind] -> [Var]
readVars = (CoreBind -> [Var]) -> [CoreBind] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CoreBind -> [Var]
forall a. CBVisitable a => a -> [Var]
readVars
  letVars :: [CoreBind] -> [Var]
letVars  = (CoreBind -> [Var]) -> [CoreBind] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CoreBind -> [Var]
forall a. CBVisitable a => a -> [Var]
letVars
  literals :: [CoreBind] -> [Literal]
literals = (CoreBind -> [Literal]) -> [CoreBind] -> [Literal]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CoreBind -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals

instance CBVisitable CoreBind where
  freeVars :: HashSet Var -> CoreBind -> [Var]
freeVars HashSet Var
env (NonRec Var
x Expr Var
e) = HashSet Var -> Expr Var -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars (HashSet Var -> [Var] -> HashSet Var
forall a. (Eq a, Hashable a) => HashSet a -> [a] -> HashSet a
extendEnv HashSet Var
env [Var
x]) Expr Var
e
  freeVars HashSet Var
env (Rec [(Var, Expr Var)]
xes)    = (Expr Var -> [Var]) -> [Expr Var] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (HashSet Var -> Expr Var -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars HashSet Var
env') [Expr Var]
es
                              where ([Var]
xs,[Expr Var]
es) = [(Var, Expr Var)] -> ([Var], [Expr Var])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Var, Expr Var)]
xes
                                    env' :: HashSet Var
env'    = HashSet Var -> [Var] -> HashSet Var
forall a. (Eq a, Hashable a) => HashSet a -> [a] -> HashSet a
extendEnv HashSet Var
env [Var]
xs

  readVars :: CoreBind -> [Var]
readVars (NonRec Var
_ Expr Var
e)     = Expr Var -> [Var]
forall a. CBVisitable a => a -> [Var]
readVars Expr Var
e
  readVars (Rec [(Var, Expr Var)]
xes)        = [[Var]] -> [Var]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [Var
x Var -> [Var] -> [Var]
forall a. Eq a => a -> [a] -> [a]
`delete` Expr Var -> [Var]
forall a. CBVisitable a => a -> [Var]
nubReadVars Expr Var
e |(Var
x, Expr Var
e) <- [(Var, Expr Var)]
xes]
    where nubReadVars :: a -> [Var]
nubReadVars = [Var] -> [Var]
forall a. Ord a => [a] -> [a]
sortNub ([Var] -> [Var]) -> (a -> [Var]) -> a -> [Var]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Var]
forall a. CBVisitable a => a -> [Var]
readVars

  letVars :: CoreBind -> [Var]
letVars (NonRec Var
x Expr Var
e)      = Var
x Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: Expr Var -> [Var]
forall a. CBVisitable a => a -> [Var]
letVars Expr Var
e
  letVars (Rec [(Var, Expr Var)]
xes)         = [Var]
xs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ (Expr Var -> [Var]) -> [Expr Var] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Expr Var -> [Var]
forall a. CBVisitable a => a -> [Var]
letVars [Expr Var]
es
    where
      ([Var]
xs, [Expr Var]
es)              = [(Var, Expr Var)] -> ([Var], [Expr Var])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Var, Expr Var)]
xes

  literals :: CoreBind -> [Literal]
literals (NonRec Var
_ Expr Var
e)      = Expr Var -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals Expr Var
e
  literals (Rec [(Var, Expr Var)]
xes)         = ((Var, Expr Var) -> [Literal]) -> [(Var, Expr Var)] -> [Literal]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Expr Var -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals (Expr Var -> [Literal])
-> ((Var, Expr Var) -> Expr Var) -> (Var, Expr Var) -> [Literal]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Var, Expr Var) -> Expr Var
forall a b. (a, b) -> b
snd) [(Var, Expr Var)]
xes

instance CBVisitable (Expr Var) where
  freeVars :: HashSet Var -> Expr Var -> [Var]
freeVars = HashSet Var -> Expr Var -> [Var]
exprFreeVars
  readVars :: Expr Var -> [Var]
readVars = Expr Var -> [Var]
forall t.
(CBVisitable (Alt t), CBVisitable (Bind t)) =>
Expr t -> [Var]
exprReadVars
  letVars :: Expr Var -> [Var]
letVars  = Expr Var -> [Var]
exprLetVars
  literals :: Expr Var -> [Literal]
literals = Expr Var -> [Literal]
forall t.
(CBVisitable (Alt t), CBVisitable (Bind t)) =>
Expr t -> [Literal]
exprLiterals

exprFreeVars :: S.HashSet Id -> Expr Id -> [Id]
exprFreeVars :: HashSet Var -> Expr Var -> [Var]
exprFreeVars = HashSet Var -> Expr Var -> [Var]
go
  where
    go :: HashSet Var -> Expr Var -> [Var]
go HashSet Var
env (Var Var
x)         = if Var
x Var -> HashSet Var -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
`S.member` HashSet Var
env then [] else [Var
x]
    go HashSet Var
env (App Expr Var
e Expr Var
a)       = HashSet Var -> Expr Var -> [Var]
go HashSet Var
env Expr Var
e [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ HashSet Var -> Expr Var -> [Var]
go HashSet Var
env Expr Var
a
    go HashSet Var
env (Lam Var
x Expr Var
e)       = HashSet Var -> Expr Var -> [Var]
go (HashSet Var -> [Var] -> HashSet Var
forall a. (Eq a, Hashable a) => HashSet a -> [a] -> HashSet a
extendEnv HashSet Var
env [Var
x]) Expr Var
e
    go HashSet Var
env (Let CoreBind
b Expr Var
e)       = HashSet Var -> CoreBind -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars HashSet Var
env CoreBind
b [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ HashSet Var -> Expr Var -> [Var]
go (HashSet Var -> [Var] -> HashSet Var
forall a. (Eq a, Hashable a) => HashSet a -> [a] -> HashSet a
extendEnv HashSet Var
env (CoreBind -> [Var]
forall t. Bind t -> [t]
bindings CoreBind
b)) Expr Var
e
    go HashSet Var
env (Tick Tickish Var
_ Expr Var
e)      = HashSet Var -> Expr Var -> [Var]
go HashSet Var
env Expr Var
e
    go HashSet Var
env (Cast Expr Var
e Coercion
_)      = HashSet Var -> Expr Var -> [Var]
go HashSet Var
env Expr Var
e
    go HashSet Var
env (Case Expr Var
e Var
x Type
_ [Alt Var]
cs) = HashSet Var -> Expr Var -> [Var]
go HashSet Var
env Expr Var
e [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ (Alt Var -> [Var]) -> [Alt Var] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (HashSet Var -> Alt Var -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars (HashSet Var -> [Var] -> HashSet Var
forall a. (Eq a, Hashable a) => HashSet a -> [a] -> HashSet a
extendEnv HashSet Var
env [Var
x])) [Alt Var]
cs
    go HashSet Var
_   Expr Var
_               = []

exprReadVars :: (CBVisitable (Alt t), CBVisitable (Bind t)) => Expr t -> [Id]
exprReadVars :: Expr t -> [Var]
exprReadVars = Expr t -> [Var]
forall t.
(CBVisitable (Alt t), CBVisitable (Bind t)) =>
Expr t -> [Var]
go
  where
    go :: Expr b -> [Var]
go (Var Var
x)             = [Var
x]
    go (App Expr b
e Expr b
a)           = (Expr b -> [Var]) -> [Expr b] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Expr b -> [Var]
go [Expr b
e, Expr b
a]
    go (Lam b
_ Expr b
e)           = Expr b -> [Var]
go Expr b
e
    go (Let Bind b
b Expr b
e)           = Bind b -> [Var]
forall a. CBVisitable a => a -> [Var]
readVars Bind b
b [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ Expr b -> [Var]
go Expr b
e
    go (Tick Tickish Var
_ Expr b
e)          = Expr b -> [Var]
go Expr b
e
    go (Cast Expr b
e Coercion
_)          = Expr b -> [Var]
go Expr b
e
    go (Case Expr b
e b
_ Type
_ [Alt b]
cs)     = Expr b -> [Var]
go Expr b
e [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ (Alt b -> [Var]) -> [Alt b] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Alt b -> [Var]
forall a. CBVisitable a => a -> [Var]
readVars [Alt b]
cs
    go Expr b
_                   = []

exprLetVars :: Expr Var -> [Var]
exprLetVars :: Expr Var -> [Var]
exprLetVars = Expr Var -> [Var]
go
  where
    go :: Expr Var -> [Var]
go (Var Var
_)             = []
    go (App Expr Var
e Expr Var
a)           = (Expr Var -> [Var]) -> [Expr Var] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Expr Var -> [Var]
go [Expr Var
e, Expr Var
a]
    go (Lam Var
x Expr Var
e)           = Var
x Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: Expr Var -> [Var]
go Expr Var
e
    go (Let CoreBind
b Expr Var
e)           = CoreBind -> [Var]
forall a. CBVisitable a => a -> [Var]
letVars CoreBind
b [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ Expr Var -> [Var]
go Expr Var
e
    go (Tick Tickish Var
_ Expr Var
e)          = Expr Var -> [Var]
go Expr Var
e
    go (Cast Expr Var
e Coercion
_)          = Expr Var -> [Var]
go Expr Var
e
    go (Case Expr Var
e Var
x Type
_ [Alt Var]
cs)     = Var
x Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: Expr Var -> [Var]
go Expr Var
e [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ (Alt Var -> [Var]) -> [Alt Var] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Alt Var -> [Var]
forall a. CBVisitable a => a -> [Var]
letVars [Alt Var]
cs
    go Expr Var
_                   = []

exprLiterals :: (CBVisitable (Alt t), CBVisitable (Bind t))
             => Expr t -> [Literal]
exprLiterals :: Expr t -> [Literal]
exprLiterals = Expr t -> [Literal]
forall t.
(CBVisitable (Alt t), CBVisitable (Bind t)) =>
Expr t -> [Literal]
go
  where
    go :: Expr b -> [Literal]
go (Lit Literal
l)             = [Literal
l]
    go (App Expr b
e Expr b
a)           = (Expr b -> [Literal]) -> [Expr b] -> [Literal]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Expr b -> [Literal]
go [Expr b
e, Expr b
a]
    go (Let Bind b
b Expr b
e)           = Bind b -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals Bind b
b [Literal] -> [Literal] -> [Literal]
forall a. [a] -> [a] -> [a]
++ Expr b -> [Literal]
go Expr b
e
    go (Lam b
_ Expr b
e)           = Expr b -> [Literal]
go Expr b
e
    go (Tick Tickish Var
_ Expr b
e)          = Expr b -> [Literal]
go Expr b
e
    go (Cast Expr b
e Coercion
_)          = Expr b -> [Literal]
go Expr b
e
    go (Case Expr b
e b
_ Type
_ [Alt b]
cs)     = Expr b -> [Literal]
go Expr b
e [Literal] -> [Literal] -> [Literal]
forall a. [a] -> [a] -> [a]
++ (Alt b -> [Literal]) -> [Alt b] -> [Literal]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Alt b -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals [Alt b]
cs
    go (Type Type
t)            = Type -> [Literal]
go' Type
t
    go Expr b
_                   = []

    go' :: Type -> [Literal]
go' (LitTy TyLit
tl)         = [TyLit -> Literal
tyLitToLit TyLit
tl]
    go' Type
_                  = []


    tyLitToLit :: TyLit -> Literal
tyLitToLit (StrTyLit FastString
fs) = ByteString -> Literal
LitString (FastString -> ByteString
bytesFS FastString
fs)
    tyLitToLit (NumTyLit Integer
i)  = LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInt (Integer -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
i) Type
intPrimTy



instance CBVisitable (Alt Var) where
  freeVars :: HashSet Var -> Alt Var -> [Var]
freeVars HashSet Var
env (AltCon
a, [Var]
xs, Expr Var
e) = HashSet Var -> AltCon -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars HashSet Var
env AltCon
a [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ HashSet Var -> Expr Var -> [Var]
forall a. CBVisitable a => HashSet Var -> a -> [Var]
freeVars (HashSet Var -> [Var] -> HashSet Var
forall a. (Eq a, Hashable a) => HashSet a -> [a] -> HashSet a
extendEnv HashSet Var
env [Var]
xs) Expr Var
e
  readVars :: Alt Var -> [Var]
readVars (AltCon
_,[Var]
_, Expr Var
e)       = Expr Var -> [Var]
forall a. CBVisitable a => a -> [Var]
readVars Expr Var
e
  letVars :: Alt Var -> [Var]
letVars  (AltCon
_,[Var]
xs,Expr Var
e)       = [Var]
xs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ Expr Var -> [Var]
forall a. CBVisitable a => a -> [Var]
letVars Expr Var
e
  literals :: Alt Var -> [Literal]
literals (AltCon
c,[Var]
_, Expr Var
e)       = AltCon -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals AltCon
c [Literal] -> [Literal] -> [Literal]
forall a. [a] -> [a] -> [a]
++ Expr Var -> [Literal]
forall a. CBVisitable a => a -> [Literal]
literals Expr Var
e

instance CBVisitable AltCon where
  freeVars :: HashSet Var -> AltCon -> [Var]
freeVars HashSet Var
_ (DataAlt DataCon
dc) = [ Var
x | AnId Var
x <- DataCon -> [TyThing]
dataConImplicitTyThings DataCon
dc]
  freeVars HashSet Var
_ AltCon
_            = []
  readVars :: AltCon -> [Var]
readVars AltCon
_              = []
  letVars :: AltCon -> [Var]
letVars  AltCon
_              = []
  literals :: AltCon -> [Literal]
literals (LitAlt Literal
l)     = [Literal
l]
  literals AltCon
_              = []

extendEnv :: (Eq a, Hashable a) => S.HashSet a -> [a] -> S.HashSet a
extendEnv :: HashSet a -> [a] -> HashSet a
extendEnv = (HashSet a -> a -> HashSet a) -> HashSet a -> [a] -> HashSet a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((a -> HashSet a -> HashSet a) -> HashSet a -> a -> HashSet a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> HashSet a -> HashSet a
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
S.insert)

bindings :: Bind t -> [t]
bindings :: Bind t -> [t]
bindings (NonRec t
x Expr t
_) = [t
x]
bindings (Rec  [(t, Expr t)]
xes  ) = ((t, Expr t) -> t) -> [(t, Expr t)] -> [t]
forall a b. (a -> b) -> [a] -> [b]
map (t, Expr t) -> t
forall a b. (a, b) -> a
fst [(t, Expr t)]
xes

----------------------------------------------------------------------------------------
-- | @BindVisitor@ allows for generic, context sensitive traversals over the @CoreBinds@ 
----------------------------------------------------------------------------------------
data CoreVisitor env acc = CoreVisitor 
  { CoreVisitor env acc -> env -> Var -> env
envF  :: env -> Var             -> env 
  , CoreVisitor env acc -> env -> acc -> Var -> acc
bindF :: env -> acc -> Var      -> acc  
  , CoreVisitor env acc -> env -> acc -> Expr Var -> acc
exprF :: env -> acc -> CoreExpr -> acc 
  }

coreVisitor :: (CoreVisitor env acc) -> env -> acc -> [CoreBind] -> acc
coreVisitor :: CoreVisitor env acc -> env -> acc -> [CoreBind] -> acc
coreVisitor CoreVisitor env acc
vis env
env acc
acc [CoreBind]
cbs   = (env, acc) -> acc
forall a b. (a, b) -> b
snd (((env, acc) -> CoreBind -> (env, acc))
-> (env, acc) -> [CoreBind] -> (env, acc)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (env, acc) -> CoreBind -> (env, acc)
step (env
env, acc
acc) [CoreBind]
cbs) 
  where
    stepXE :: (env, acc) -> (Var, Expr Var) -> (env, acc)
stepXE (env
env, acc
acc) (Var
x,Expr Var
e)   = (env
env', env -> acc -> Expr Var -> acc
stepE env
env' acc
acc'   Expr Var
e)  
      where 
        env' :: env
env'                  = CoreVisitor env acc -> env -> Var -> env
forall env acc. CoreVisitor env acc -> env -> Var -> env
envF  CoreVisitor env acc
vis env
env     Var
x 
        acc' :: acc
acc'                  = CoreVisitor env acc -> env -> acc -> Var -> acc
forall env acc. CoreVisitor env acc -> env -> acc -> Var -> acc
bindF CoreVisitor env acc
vis env
env acc
acc Var
x  

    step :: (env, acc) -> CoreBind -> (env, acc)
step (env, acc)
ea (NonRec Var
x Expr Var
e)      = (env, acc) -> (Var, Expr Var) -> (env, acc)
stepXE (env, acc)
ea (Var
x, Expr Var
e) 
    step (env, acc)
ea (Rec    [(Var, Expr Var)]
xes)      = ((env, acc) -> (Var, Expr Var) -> (env, acc))
-> (env, acc) -> [(Var, Expr Var)] -> (env, acc)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (env, acc) -> (Var, Expr Var) -> (env, acc)
stepXE (env, acc)
ea [(Var, Expr Var)]
xes 

    -- step (env, acc) (NonRec x e) = stepXE env acc x e 
    -- step (env, acc) (Rec    xes) = (env', foldl' (stepE env') acc' es) 
      -- where 
        -- acc'                     = foldl' (bindF vis env') acc xs
        -- env'                     = foldl' (envF  vis)      env xs 
        -- xs                       = fst <$> xes 
        -- es                       = snd <$> xes
        -- foldl' (\(env, acc) (x, e) ->  )

    stepE :: env -> acc -> Expr Var -> acc
stepE env
env acc
acc Expr Var
e              = env -> acc -> Expr Var -> acc
goE env
env (CoreVisitor env acc -> env -> acc -> Expr Var -> acc
forall env acc.
CoreVisitor env acc -> env -> acc -> Expr Var -> acc
exprF CoreVisitor env acc
vis env
env acc
acc Expr Var
e) Expr Var
e 

    goE :: env -> acc -> Expr Var -> acc
goE env
_   acc
acc (Var Var
_)          = acc
acc 
    goE env
env acc
acc (App Expr Var
e1 Expr Var
e2)      = env -> acc -> Expr Var -> acc
stepE  env
env (env -> acc -> Expr Var -> acc
stepE env
env acc
acc Expr Var
e1) Expr Var
e2 
    goE env
env acc
acc (Tick Tickish Var
_ Expr Var
e)       = env -> acc -> Expr Var -> acc
stepE  env
env acc
acc Expr Var
e 
    goE env
env acc
acc (Cast Expr Var
e Coercion
_)       = env -> acc -> Expr Var -> acc
stepE  env
env acc
acc Expr Var
e  
    goE env
env acc
acc (Lam Var
x Expr Var
e)        = (env, acc) -> acc
forall a b. (a, b) -> b
snd ((env, acc) -> (Var, Expr Var) -> (env, acc)
stepXE (env
env, acc
acc) (Var
x, Expr Var
e))
    goE env
env acc
acc (Let CoreBind
b Expr Var
e)        = env -> acc -> Expr Var -> acc
stepE env
env' acc
acc' Expr Var
e where (env
env', acc
acc') = (env, acc) -> CoreBind -> (env, acc)
step (env
env, acc
acc) CoreBind
b 
    goE env
env acc
acc (Case Expr Var
e Var
_ Type
_ [Alt Var]
cs)  = (acc -> Alt Var -> acc) -> acc -> [Alt Var] -> acc
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (env -> acc -> Alt Var -> acc
goC env
env) (env -> acc -> Expr Var -> acc
stepE env
env acc
acc Expr Var
e) [Alt Var]
cs
    goE env
_   acc
acc Expr Var
_                = acc
acc 

    goC :: env -> acc -> Alt Var -> acc
goC env
env acc
acc (AltCon
_, [Var]
xs, Expr Var
e)       = env -> acc -> Expr Var -> acc
stepE  env
env' acc
acc' Expr Var
e 
      where
        env' :: env
env'                     = (env -> Var -> env) -> env -> [Var] -> env
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (CoreVisitor env acc -> env -> Var -> env
forall env acc. CoreVisitor env acc -> env -> Var -> env
envF  CoreVisitor env acc
vis)     env
env [Var]
xs 
        acc' :: acc
acc'                     = (acc -> Var -> acc) -> acc -> [Var] -> acc
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (CoreVisitor env acc -> env -> acc -> Var -> acc
forall env acc. CoreVisitor env acc -> env -> acc -> Var -> acc
bindF CoreVisitor env acc
vis env
env) acc
acc [Var]
xs