Note [Care with unlifted bindings]
Consider (#22998) f x = let x::ByteArray# = <some literal> n::Natural = NB x in wombat @192827 (n |> co) where co :: Natural ~ KnownNat 192827 wombat :: forall (n:Nat). KnownNat n => blah Left to itself, the specialiser would float the bindings for `x` and `n` to top level, so we can specialise `wombat`. But we can't have a top-level ByteArray# (see Note [Core letrec invariant] in GHC.Core). Boo. This is pretty exotic, so we take a simple way out: in specBind (the NonRec case) do not float the binding itself unless it satisfies exprIsTopLevelBindable. This is conservative: maybe the RHS of `x` has a free var that would stop it floating to top level anyway; but that is hard to spot (since we don't know what the non-top-level in-scope binders are) and rare (since the binding must satisfy Note [Core let-can-float invariant] in GHC.Core).
References 2
- Core let-can-float invariant GHC.Core
- Core letrec invariant GHC.Core
Referenced by 1
- GHC.Core.Opt.Specialise call site