Note [Preserve RuntimeRep info in cast w/w]
We must not do cast w/w when the presence of the coercion is needed in order
to determine the runtime representation.
Example:
Suppose we have a type family:
type F :: RuntimeRep
type family F where
F = LiftedRep
together with a type `ty :: TYPE F` and a top-level binding
a :: ty |> TYPE F[0]
The kind of `ty |> TYPE F[0]` is `LiftedRep`, so `a` is a top-level lazy binding.
However, were we to apply cast w/w, we would get:
b :: ty
b = ...
a :: ty |> TYPE F[0]
a = b `cast` GRefl (TYPE F[0])
Now we are in trouble because `ty :: TYPE F` does not have a known runtime
representation, because we need to be able to reduce the nullary type family
application `F` to find that out.
Conclusion: only do cast w/w when doing so would not lose the RuntimeRep
information. That is, when handling `Cast rhs co`, don't attempt cast w/w
unless the kind of the type of rhs is concrete, in the sense of
Note [Concrete types] in GHC.Tc.Utils.Concrete. References 1
- Concrete types GHC.Tc.Utils.Concrete
Referenced by 1
- GHC.Core.Opt.Simplify.Iteration call site