GHC no longer instantiates representation-polymorphic newtype constructors
Consider the following program:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE UnliftedNewtypes #-}
import GHC.Exts
newtype N r (a :: TYPE r) = MkN a
foo :: Int# -> N IntRep Int#
foo i = MkN i
On GHC 9.2, the output of -ddump-ds-preopt
is:
foo = \ (i :: Int#) -> (\ (ds :: Int#) -> MkN @'IntRep @Int# ds) i
That is, we have instantiated the representation-polymorphic MkN :: forall r (a :: TYPE r) . a -> N r a
, with MkN @IntRep @Int#
.
However, on GHC HEAD, we get:
foo = \ (i :: Int#) -> (\ @(r :: RuntimeRep) @(a :: TYPE r) (ds :: a) -> MkN @r @a ds) i
here we have a representation-polymorphic binder ds :: a
!
I think this issue was introduced in !5640 (closed). There used to be logic in tc_infer_id
to instantiate a representation-polymorphic data constructor, but that logic seems to have vanished entirely, and the new tcInferDataCon
function does not do any instantiation. It's left with the original argument types, and thus dsConLike
gets passed argument types which don't have a fixed runtime representation.
I think we should have an invariant that the argument types stored in ConLikeTc
have a syntactically fixed RuntimeRep, which is necessary as they are the types of variables bound in a lambda (created by dsConLike
), and enforce it by instantiating the newtype constructor.
This issue is causing me trouble with the implementation of PHASE 2 of FixedRuntimeRep.