    {-
    (c) The University of Glasgow 2006
    (c) The AQUA Project, Glasgow University, 1996-1998

    This module contains "tidying" code for *nested* expressions, bindings, rules.
    The code for *top-level* bindings is in GHC.Iface.Tidy.
    -}

    {-# LANGUAGE CPP #-}
    {-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
    module GHC.Core.Tidy (
            tidyExpr, tidyRules, tidyUnfolding
        ) where

    #include "HsVersions.h"

    import GHC.Prelude

    import GHC.Core
    import GHC.Core.Seq ( seqUnfolding )
    import GHC.Types.Id
    import GHC.Types.Id.Info
    import GHC.Types.Demand ( zapDmdEnvSig )
    import GHC.Core.Type     ( tidyType, tidyVarBndr )
    import GHC.Core.Coercion ( tidyCo )
    import GHC.Types.Var
    import GHC.Types.Var.Env
    import GHC.Types.Unique (getUnique)
    import GHC.Types.Unique.FM
    import GHC.Types.Name hiding (tidyNameOcc)
    import GHC.Types.SrcLoc
    import GHC.Types.Tickish
    import GHC.Data.Maybe
    import Data.List (mapAccumL)

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Tidying expressions, rules}
    *                                                                      *
    ************************************************************************
    -}

    tidyBind :: TidyEnv
             -> CoreBind
             ->  (TidyEnv, CoreBind)

    tidyBind :: TidyEnv -> CoreBind -> (TidyEnv, CoreBind)
    tidyBind TidyEnv
    env (NonRec Id
    bndr Expr Id
    rhs)
      = TidyEnv -> TidyEnv -> Id -> (TidyEnv, Id)
    tidyLetBndr TidyEnv
    env TidyEnv
    env Id
    bndr forall a b. a -> (a -> b) -> b
    =: \ (TidyEnv
    env', Id
    bndr') ->
        (TidyEnv
    env', forall b. b -> Expr b -> Bind b
    NonRec Id
    bndr' (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env' Expr Id
    rhs))

    tidyBind TidyEnv
    env (Rec [(Id, Expr Id)]
    prs)
      = let
           ([Id]
    bndrs, [Expr Id]
    rhss)  = forall a b. [(a, b)] -> ([a], [b])
    unzip [(Id, Expr Id)]
    prs
           (TidyEnv
    env', [Id]
    bndrs') = forall (t :: * -> *) s a b.
    Traversable t =>
    (s -> a -> (s, b)) -> s -> t a -> (s, t b)
    mapAccumL (TidyEnv -> TidyEnv -> Id -> (TidyEnv, Id)
    tidyLetBndr TidyEnv
    env') TidyEnv
    env [Id]
    bndrs
        in
        forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env') [Expr Id]
    rhss forall a b. a -> (a -> b) -> b
    =: \ [Expr Id]
    rhss' ->
        (TidyEnv
    env', forall b. [(b, Expr b)] -> Bind b
    Rec (forall a b. [a] -> [b] -> [(a, b)]
    zip [Id]
    bndrs' [Expr Id]
    rhss'))

    ------------  Expressions  --------------
    tidyExpr :: TidyEnv -> CoreExpr -> CoreExpr
    tidyExpr :: TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env (Var Id
    v)       = forall b. Id -> Expr b
    Var (TidyEnv -> Id -> Id
    tidyVarOcc TidyEnv
    env Id
    v)
    tidyExpr TidyEnv
    env (Type Type
    ty)     = forall b. Type -> Expr b
    Type (TidyEnv -> Type -> Type
    tidyType TidyEnv
    env Type
    ty)
    tidyExpr TidyEnv
    env (Coercion Coercion
    co) = forall b. Coercion -> Expr b
    Coercion (TidyEnv -> Coercion -> Coercion
    tidyCo TidyEnv
    env Coercion
    co)
    tidyExpr TidyEnv
    _   (Lit Literal
    lit)     = forall b. Literal -> Expr b
    Lit Literal
    lit
    tidyExpr TidyEnv
    env (App Expr Id
    f Expr Id
    a)     = forall b. Expr b -> Expr b -> Expr b
    App (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env Expr Id
    f) (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env Expr Id
    a)
    tidyExpr TidyEnv
    env (Tick CoreTickish
    t Expr Id
    e)    = forall b. CoreTickish -> Expr b -> Expr b
    Tick (TidyEnv -> CoreTickish -> CoreTickish
    tidyTickish TidyEnv
    env CoreTickish
    t) (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env Expr Id
    e)
    tidyExpr TidyEnv
    env (Cast Expr Id
    e Coercion
    co)   = forall b. Expr b -> Coercion -> Expr b
    Cast (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env Expr Id
    e) (TidyEnv -> Coercion -> Coercion
    tidyCo TidyEnv
    env Coercion
    co)

    tidyExpr TidyEnv
    env (Let CoreBind
    b Expr Id
    e)
      = TidyEnv -> CoreBind -> (TidyEnv, CoreBind)
    tidyBind TidyEnv
    env CoreBind
    b      forall a b. a -> (a -> b) -> b
    =: \ (TidyEnv
    env', CoreBind
    b') ->
        forall b. Bind b -> Expr b -> Expr b
    Let CoreBind
    b' (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env' Expr Id
    e)

    tidyExpr TidyEnv
    env (Case Expr Id
    e Id
    b Type
    ty [Alt Id]
    alts)
      = TidyEnv -> Id -> (TidyEnv, Id)
    tidyBndr TidyEnv
    env Id
    b  forall a b. a -> (a -> b) -> b
    =: \ (TidyEnv
    env', Id
    b) ->
        forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
    Case (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env Expr Id
    e) Id
    b (TidyEnv -> Type -> Type
    tidyType TidyEnv
    env Type
    ty)
             (forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> Alt Id -> Alt Id
    tidyAlt TidyEnv
    env') [Alt Id]
    alts)

    tidyExpr TidyEnv
    env (Lam Id
    b Expr Id
    e)
      = TidyEnv -> Id -> (TidyEnv, Id)
    tidyBndr TidyEnv
    env Id
    b      forall a b. a -> (a -> b) -> b
    =: \ (TidyEnv
    env', Id
    b) ->
        forall b. b -> Expr b -> Expr b
    Lam Id
    b (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env' Expr Id
    e)

    ------------  Case alternatives  --------------
    tidyAlt :: TidyEnv -> CoreAlt -> CoreAlt
    tidyAlt :: TidyEnv -> Alt Id -> Alt Id
    tidyAlt TidyEnv
    env (Alt AltCon
    con [Id]
    vs Expr Id
    rhs)
      = TidyEnv -> [Id] -> (TidyEnv, [Id])
    tidyBndrs TidyEnv
    env [Id]
    vs    forall a b. a -> (a -> b) -> b
    =: \ (TidyEnv
    env', [Id]
    vs) ->
        (forall b. AltCon -> [b] -> Expr b -> Alt b
    Alt AltCon
    con [Id]
    vs (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env' Expr Id
    rhs))

    ------------  Tickish  --------------
    tidyTickish :: TidyEnv -> CoreTickish -> CoreTickish
    tidyTickish :: TidyEnv -> CoreTickish -> CoreTickish
    tidyTickish TidyEnv
    env (Breakpoint XBreakpoint 'TickishPassCore
    ext Int
    ix [XTickishId 'TickishPassCore]
    ids)
      = forall (pass :: TickishPass).
    XBreakpoint pass -> Int -> [XTickishId pass] -> GenTickish pass
    Breakpoint XBreakpoint 'TickishPassCore
    ext Int
    ix (forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> Id -> Id
    tidyVarOcc TidyEnv
    env) [XTickishId 'TickishPassCore]
    ids)
    tidyTickish TidyEnv
    _   CoreTickish
    other_tickish       = CoreTickish
    other_tickish

    ------------  Rules  --------------
    tidyRules :: TidyEnv -> [CoreRule] -> [CoreRule]
    tidyRules :: TidyEnv -> [CoreRule] -> [CoreRule]
    tidyRules TidyEnv
    _   [] = []
    tidyRules TidyEnv
    env (CoreRule
    rule : [CoreRule]
    rules)
      = TidyEnv -> CoreRule -> CoreRule
    tidyRule TidyEnv
    env CoreRule
    rule           forall a b. a -> (a -> b) -> b
    =: \ CoreRule
    rule ->
        TidyEnv -> [CoreRule] -> [CoreRule]
    tidyRules TidyEnv
    env [CoreRule]
    rules         forall a b. a -> (a -> b) -> b
    =: \ [CoreRule]
    rules ->
        (CoreRule
    rule forall a. a -> [a] -> [a]
    : [CoreRule]
    rules)

    tidyRule :: TidyEnv -> CoreRule -> CoreRule
    tidyRule :: TidyEnv -> CoreRule -> CoreRule
    tidyRule TidyEnv
    _   rule :: CoreRule
    rule@(BuiltinRule {}) = CoreRule
    rule
    tidyRule TidyEnv
    env rule :: CoreRule
    rule@(Rule { ru_bndrs :: CoreRule -> [Id]
    ru_bndrs = [Id]
    bndrs, ru_args :: CoreRule -> [Expr Id]
    ru_args = [Expr Id]
    args, ru_rhs :: CoreRule -> Expr Id
    ru_rhs = Expr Id
    rhs,
                              ru_fn :: CoreRule -> Name
    ru_fn = Name
    fn, ru_rough :: CoreRule -> [Maybe Name]
    ru_rough = [Maybe Name]
    mb_ns })
      = TidyEnv -> [Id] -> (TidyEnv, [Id])
    tidyBndrs TidyEnv
    env [Id]
    bndrs         forall a b. a -> (a -> b) -> b
    =: \ (TidyEnv
    env', [Id]
    bndrs) ->
        forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env') [Expr Id]
    args    forall a b. a -> (a -> b) -> b
    =: \ [Expr Id]
    args ->
        CoreRule
    rule { ru_bndrs :: [Id]
    ru_bndrs = [Id]
    bndrs, ru_args :: [Expr Id]
    ru_args = [Expr Id]
    args,
               ru_rhs :: Expr Id
    ru_rhs   = TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    env' Expr Id
    rhs,
               ru_fn :: Name
    ru_fn    = TidyEnv -> Name -> Name
    tidyNameOcc TidyEnv
    env Name
    fn,
               ru_rough :: [Maybe Name]
    ru_rough = forall a b. (a -> b) -> [a] -> [b]
    map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (TidyEnv -> Name -> Name
    tidyNameOcc TidyEnv
    env')) [Maybe Name]
    mb_ns }

    {-
    ************************************************************************
    *                                                                      *
    \subsection{Tidying non-top-level binders}
    *                                                                      *
    ************************************************************************
    -}

    tidyNameOcc :: TidyEnv -> Name -> Name
    -- In rules and instances, we have Names, and we must tidy them too
    -- Fortunately, we can lookup in the VarEnv with a name
    tidyNameOcc :: TidyEnv -> Name -> Name
    tidyNameOcc (TidyOccEnv
    _, VarEnv Id
    var_env) Name
    n = case forall key elt. UniqFM key elt -> Unique -> Maybe elt
    lookupUFM_Directly VarEnv Id
    var_env (forall a. Uniquable a => a -> Unique
    getUnique Name
    n) of
                                    Maybe Id
    Nothing -> Name
    n
                                    Just Id
    v  -> Id -> Name
    idName Id
    v

    tidyVarOcc :: TidyEnv -> Var -> Var
    tidyVarOcc :: TidyEnv -> Id -> Id
    tidyVarOcc (TidyOccEnv
    _, VarEnv Id
    var_env) Id
    v = forall a. VarEnv a -> Id -> Maybe a
    lookupVarEnv VarEnv Id
    var_env Id
    v forall a. Maybe a -> a -> a
    `orElse` Id
    v

    -- tidyBndr is used for lambda and case binders
    tidyBndr :: TidyEnv -> Var -> (TidyEnv, Var)
    tidyBndr :: TidyEnv -> Id -> (TidyEnv, Id)
    tidyBndr TidyEnv
    env Id
    var
      | Id -> Bool
    isTyCoVar Id
    var = TidyEnv -> Id -> (TidyEnv, Id)
    tidyVarBndr TidyEnv
    env Id
    var
      | Bool
    otherwise     = TidyEnv -> Id -> (TidyEnv, Id)
    tidyIdBndr TidyEnv
    env Id
    var

    tidyBndrs :: TidyEnv -> [Var] -> (TidyEnv, [Var])
    tidyBndrs :: TidyEnv -> [Id] -> (TidyEnv, [Id])
    tidyBndrs TidyEnv
    env [Id]
    vars = forall (t :: * -> *) s a b.
    Traversable t =>
    (s -> a -> (s, b)) -> s -> t a -> (s, t b)
    mapAccumL TidyEnv -> Id -> (TidyEnv, Id)
    tidyBndr TidyEnv
    env [Id]
    vars

    -- Non-top-level variables, not covars
    tidyIdBndr :: TidyEnv -> Id -> (TidyEnv, Id)
    tidyIdBndr :: TidyEnv -> Id -> (TidyEnv, Id)
    tidyIdBndr env :: TidyEnv
    env@(TidyOccEnv
    tidy_env, VarEnv Id
    var_env) Id
    id
      = -- Do this pattern match strictly, otherwise we end up holding on to
        -- stuff in the OccName.
        case TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
    tidyOccName TidyOccEnv
    tidy_env (forall a. NamedThing a => a -> OccName
    getOccName Id
    id) of { (TidyOccEnv
    tidy_env', OccName
    occ') ->
        let
            -- Give the Id a fresh print-name, *and* rename its type
            -- The SrcLoc isn't important now,
            -- though we could extract it from the Id
            --
            ty' :: Type
    ty'      = TidyEnv -> Type -> Type
    tidyType TidyEnv
    env (Id -> Type
    idType Id
    id)
            mult' :: Type
    mult'    = TidyEnv -> Type -> Type
    tidyType TidyEnv
    env (Id -> Type
    idMult Id
    id)
            name' :: Name
    name'    = Unique -> OccName -> SrcSpan -> Name
    mkInternalName (Id -> Unique
    idUnique Id
    id) OccName
    occ' SrcSpan
    noSrcSpan
            id' :: Id
    id'      = HasDebugCallStack => Name -> Type -> Type -> IdInfo -> Id
    mkLocalIdWithInfo Name
    name' Type
    mult' Type
    ty' IdInfo
    new_info
            var_env' :: VarEnv Id
    var_env' = forall a. VarEnv a -> Id -> a -> VarEnv a
    extendVarEnv VarEnv Id
    var_env Id
    id Id
    id'

            -- Note [Tidy IdInfo]
            new_info :: IdInfo
    new_info = IdInfo
    vanillaIdInfo IdInfo -> OccInfo -> IdInfo
    `setOccInfo` IdInfo -> OccInfo
    occInfo IdInfo
    old_info
                                     IdInfo -> Unfolding -> IdInfo
    `setUnfoldingInfo` Unfolding
    new_unf
                                      -- see Note [Preserve OneShotInfo]
                                     IdInfo -> OneShotInfo -> IdInfo
    `setOneShotInfo` IdInfo -> OneShotInfo
    oneShotInfo IdInfo
    old_info
            old_info :: IdInfo
    old_info = HasDebugCallStack => Id -> IdInfo
    idInfo Id
    id
            old_unf :: Unfolding
    old_unf  = IdInfo -> Unfolding
    unfoldingInfo IdInfo
    old_info
            new_unf :: Unfolding
    new_unf  = Unfolding -> Unfolding
    zapUnfolding Unfolding
    old_unf  -- See Note [Preserve evaluatedness]
        in
        ((TidyOccEnv
    tidy_env', VarEnv Id
    var_env'), Id
    id')
       }

    tidyLetBndr :: TidyEnv         -- Knot-tied version for unfoldings
                -> TidyEnv         -- The one to extend
                -> Id -> (TidyEnv, Id)
    -- Used for local (non-top-level) let(rec)s
    -- Just like tidyIdBndr above, but with more IdInfo
    tidyLetBndr :: TidyEnv -> TidyEnv -> Id -> (TidyEnv, Id)
    tidyLetBndr TidyEnv
    rec_tidy_env env :: TidyEnv
    env@(TidyOccEnv
    tidy_env, VarEnv Id
    var_env) Id
    id
      = case TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
    tidyOccName TidyOccEnv
    tidy_env (forall a. NamedThing a => a -> OccName
    getOccName Id
    id) of { (TidyOccEnv
    tidy_env', OccName
    occ') ->
        let
            ty' :: Type
    ty'      = TidyEnv -> Type -> Type
    tidyType TidyEnv
    env (Id -> Type
    idType Id
    id)
            mult' :: Type
    mult'    = TidyEnv -> Type -> Type
    tidyType TidyEnv
    env (Id -> Type
    idMult Id
    id)
            name' :: Name
    name'    = Unique -> OccName -> SrcSpan -> Name
    mkInternalName (Id -> Unique
    idUnique Id
    id) OccName
    occ' SrcSpan
    noSrcSpan
            details :: IdDetails
    details  = Id -> IdDetails
    idDetails Id
    id
            id' :: Id
    id'      = IdDetails -> Name -> Type -> Type -> IdInfo -> Id
    mkLocalVar IdDetails
    details Name
    name' Type
    mult' Type
    ty' IdInfo
    new_info
            var_env' :: VarEnv Id
    var_env' = forall a. VarEnv a -> Id -> a -> VarEnv a
    extendVarEnv VarEnv Id
    var_env Id
    id Id
    id'

            -- Note [Tidy IdInfo]
            -- We need to keep around any interesting strictness and
            -- demand info because later on we may need to use it when
            -- converting to A-normal form.
            -- eg.
            --      f (g x),  where f is strict in its argument, will be converted
            --      into  case (g x) of z -> f z  by CorePrep, but only if f still
            --      has its strictness info.
            --
            -- Similarly for the demand info - on a let binder, this tells
            -- CorePrep to turn the let into a case.
            -- But: Remove the usage demand here
            --      (See Note [Zapping DmdEnv after Demand Analyzer] in GHC.Core.Opt.WorkWrap)
            --
            -- Similarly arity info for eta expansion in CorePrep
            -- Don't attempt to recompute arity here; this is just tidying!
            -- Trying to do so led to #17294
            --
            -- Set inline-prag info so that we preserve it across
            -- separate compilation boundaries
            old_info :: IdInfo
    old_info = HasDebugCallStack => Id -> IdInfo
    idInfo Id
    id
            new_info :: IdInfo
    new_info = IdInfo
    vanillaIdInfo
                        IdInfo -> OccInfo -> IdInfo
    `setOccInfo`        IdInfo -> OccInfo
    occInfo IdInfo
    old_info
                        IdInfo -> Int -> IdInfo
    `setArityInfo`      IdInfo -> Int
    arityInfo IdInfo
    old_info
                        IdInfo -> StrictSig -> IdInfo
    `setStrictnessInfo` StrictSig -> StrictSig
    zapDmdEnvSig (IdInfo -> StrictSig
    strictnessInfo IdInfo
    old_info)
                        IdInfo -> Demand -> IdInfo
    `setDemandInfo`     IdInfo -> Demand
    demandInfo IdInfo
    old_info
                        IdInfo -> InlinePragma -> IdInfo
    `setInlinePragInfo` IdInfo -> InlinePragma
    inlinePragInfo IdInfo
    old_info
                        IdInfo -> Unfolding -> IdInfo
    `setUnfoldingInfo`  Unfolding
    new_unf

            old_unf :: Unfolding
    old_unf = IdInfo -> Unfolding
    unfoldingInfo IdInfo
    old_info
            new_unf :: Unfolding
    new_unf | Unfolding -> Bool
    isStableUnfolding Unfolding
    old_unf = TidyEnv -> Unfolding -> Unfolding -> Unfolding
    tidyUnfolding TidyEnv
    rec_tidy_env Unfolding
    old_unf Unfolding
    old_unf
                    | Bool
    otherwise                 = Unfolding -> Unfolding
    zapUnfolding Unfolding
    old_unf
                                                  -- See Note [Preserve evaluatedness]

        in
        ((TidyOccEnv
    tidy_env', VarEnv Id
    var_env'), Id
    id') }

    ------------ Unfolding  --------------
    tidyUnfolding :: TidyEnv -> Unfolding -> Unfolding -> Unfolding
    tidyUnfolding :: TidyEnv -> Unfolding -> Unfolding -> Unfolding
    tidyUnfolding TidyEnv
    tidy_env df :: Unfolding
    df@(DFunUnfolding { df_bndrs :: Unfolding -> [Id]
    df_bndrs = [Id]
    bndrs, df_args :: Unfolding -> [Expr Id]
    df_args = [Expr Id]
    args }) Unfolding
    _
      = Unfolding
    df { df_bndrs :: [Id]
    df_bndrs = [Id]
    bndrs', df_args :: [Expr Id]
    df_args = forall a b. (a -> b) -> [a] -> [b]
    map (TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    tidy_env') [Expr Id]
    args }
      where
        (TidyEnv
    tidy_env', [Id]
    bndrs') = TidyEnv -> [Id] -> (TidyEnv, [Id])
    tidyBndrs TidyEnv
    tidy_env [Id]
    bndrs

    tidyUnfolding TidyEnv
    tidy_env
                  unf :: Unfolding
    unf@(CoreUnfolding { uf_tmpl :: Unfolding -> Expr Id
    uf_tmpl = Expr Id
    unf_rhs, uf_src :: Unfolding -> UnfoldingSource
    uf_src = UnfoldingSource
    src })
                  Unfolding
    unf_from_rhs
      | UnfoldingSource -> Bool
    isStableSource UnfoldingSource
    src
      = Unfolding -> Unfolding
    seqIt forall a b. (a -> b) -> a -> b
    $ Unfolding
    unf { uf_tmpl :: Expr Id
    uf_tmpl = TidyEnv -> Expr Id -> Expr Id
    tidyExpr TidyEnv
    tidy_env Expr Id
    unf_rhs }    -- Preserves OccInfo
        -- This seqIt avoids a space leak: otherwise the uf_is_value,
        -- uf_is_conlike, ... fields may retain a reference to the
        -- pre-tidied expression forever (GHC.CoreToIface doesn't look at them)

      | Bool
    otherwise
      = Unfolding
    unf_from_rhs
      where seqIt :: Unfolding -> Unfolding
    seqIt Unfolding
    unf = Unfolding -> ()
    seqUnfolding Unfolding
    unf seq :: forall a b. a -> b -> b
    `seq` Unfolding
    unf
    tidyUnfolding TidyEnv
    _ Unfolding
    unf Unfolding
    _ = Unfolding
    unf     -- NoUnfolding or OtherCon

    {-
    Note [Tidy IdInfo]
    ~~~~~~~~~~~~~~~~~~
    All nested Ids now have the same IdInfo, namely vanillaIdInfo, which
    should save some space; except that we preserve occurrence info for
    two reasons:

      (a) To make printing tidy core nicer

      (b) Because we tidy RULES and InlineRules, which may then propagate
          via --make into the compilation of the next module, and we want
          the benefit of that occurrence analysis when we use the rule or
          or inline the function.  In particular, it's vital not to lose
          loop-breaker info, else we get an infinite inlining loop

    Note that tidyLetBndr puts more IdInfo back.

    Note [Preserve evaluatedness]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Consider
      data T = MkT !Bool
      ....(case v of MkT y ->
           let z# = case y of
                      True -> 1#
                      False -> 2#
           in ...)

    The z# binding is ok because the RHS is ok-for-speculation,
    but Lint will complain unless it can *see* that.  So we
    preserve the evaluated-ness on 'y' in tidyBndr.

    (Another alternative would be to tidy unboxed lets into cases,
    but that seems more indirect and surprising.)

    Note [Preserve OneShotInfo]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    We keep the OneShotInfo because we want it to propagate into the interface.
    Not all OneShotInfo is determined by a compiler analysis; some is added by a
    call of GHC.Exts.oneShot, which is then discarded before the end of the
    optimisation pipeline, leaving only the OneShotInfo on the lambda. Hence we
    must preserve this info in inlinings. See Note [The oneShot function] in GHC.Types.Id.Make.

    This applies to lambda binders only, hence it is stored in IfaceLamBndr.
    -}

    (=:) :: a -> (a -> b) -> b
    a
    m =: :: forall a b. a -> (a -> b) -> b
    =: a -> b
    k = a
    m seq :: forall a b. a -> b -> b
    `seq` a -> b
    k a
    m