-- | For all used constructors in expressions and patterns,
--   return the TyCons they originate from
exprTyCons :: CoreExpr -> Set TyCon
exprTyCons e0 = case e0 of
    Case e x t alts -> S.unions (varTyCons x:tyTyCons t:exprTyCons e:map altTyCons alts)
    App e1 e2       -> S.union (exprTyCons e1) (exprTyCons e2)
    Let bs e        -> S.unions (exprTyCons e:map exprTyCons (rhssOfBind bs))
    Lam _ e         -> exprTyCons e
    Cast e _        -> exprTyCons e
    Tick _ e        -> exprTyCons e
    Var x           -> varTyCons x
    Type t          -> tyTyCons t
    Coercion{}      -> S.empty
    Lit{}           -> tyTyCons (exprType e0)
exprTyCons :: CoreExpr -> Set TyCon
exprTyCons e0 = case e0 of
    Case e x t alts -> S.unions (varTyCons x:tyTyCons t:exprTyCons e:map altTyCons alts)
    App e1 e2       -> S.union (exprTyCons e1) (exprTyCons e2)
    Let bs e        -> S.unions (exprTyCons e:map exprTyCons (rhssOfBind bs))
    Lam _ e         -> exprTyCons e
    Cast e _        -> exprTyCons e
    Tick _ e        -> exprTyCons e
    Var x           -> varTyCons x
    Type t          -> tyTyCons t
    Coercion{}      -> S.empty
    Lit{}           -> tyTyCons (exprType e0)
exprTyCons e0 = case e0 of
    Case e x t alts -> S.unions (varTyCons x:tyTyCons t:exprTyCons e:map altTyCons alts)
    App e1 e2       -> S.union (exprTyCons e1) (exprTyCons e2)
    Let bs e        -> S.unions (exprTyCons e:map exprTyCons (rhssOfBind bs))
    Lam _ e         -> exprTyCons e
    Cast e _        -> exprTyCons e
    Tick _ e        -> exprTyCons e
    Var x           -> varTyCons x
    Type t          -> tyTyCons t
    Coercion{}      -> S.empty
    Lit{}           -> tyTyCons (exprType e0)