Note [RuntimeUnkTv]

GHC/Runtime/Heap/Inspect.hs:625 compiler 1 ticket

In the GHCi debugger we use unification variables whose MetaInfo is
RuntimeUnkTv.  The special property of a RuntimeUnkTv is that it can
unify with a polytype (see GHC.Tc.Utils.Unify.checkTypeEq).
If we don't do this `:print <term>` will fail if the type of <term>
has nested `forall`s or `=>`s.

This is because the GHCi debugger's internals will attempt to unify a
metavariable with the type of <term> and then display the result, but
if the type has nested `forall`s or `=>`s, then unification will fail
unless we do something special.  As a result, `:print` will bail out
and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a
metavariable).

Beware: <term> can have nested `forall`s even if its definition doesn't use
RankNTypes! Here is an example from #14828:

  class Functor f where
    fmap :: (a -> b) -> f a -> f b

Somewhat surprisingly, `:print fmap` considers the type of fmap to have
nested foralls. This is because the GHCi debugger sees the type
`fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`.
We could envision deeply instantiating this type to get the type
`forall f a b. Functor f => (a -> b) -> f a -> f b`,
but this trick wouldn't work for higher-rank types.

Instead, we adopt a simpler fix: allow RuntimeUnkTv to unify with a
polytype (specifically, see ghci_tv in GHC.Tc.Utils.Unify.preCheck).
This allows metavariables to unify with types that have
nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap`
display as
`fmap = (_t1::forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b)`,
as expected.

References 0

This Note does not link to any other.

Referenced by 2