Note [Representation-polymorphic Ids with no binding]

GHC/Tc/Utils/Concrete.hs:382 compiler

We cannot have representation-polymorphic or levity-polymorphic
function arguments. See Note [Representation polymorphism invariants]
in GHC.Core.  That is checked in 'GHC.Tc.Gen.App.tcInstFun', see the call
to 'matchActualFunTy', which performs the representation-polymorphism
check.

However, some special Ids have representation-polymorphic argument
types. These are all GHC built-ins or data constructors. They have no binding;
instead they have compulsory unfoldings. Specifically, these Ids are:

1. Some wired-in Ids, such as coerce, oneShot and unsafeCoerce# (which is only
   partly wired-in),
2. Representation-polymorphic primops, such as raise#.
3. Representation-polymorphic data constructors: unboxed tuples
   and unboxed sums.
4. Newtype constructors with `UnliftedNewtypes` which have
   a representation-polymorphic argument.

For (1) consider
  badId :: forall r (a :: TYPE r). a -> a
  badId = unsafeCoerce# @r @r @a @a

The (partly) wired-in function
  unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
                   (a :: TYPE r1) (b :: TYPE r2).
                   a -> b
has a convenient but representation-polymorphic type. It has no
binding; instead it has a compulsory unfolding, after which we
would have
  badId = /\r /\(a :: TYPE r). \(x::a). ...body of unsafeCorece#...
And this is no good because of that rep-poly \(x::a).  So we want
to reject this.

On the other hand
  goodId :: forall (a :: Type). a -> a
  goodId = unsafeCoerce# @LiftedRep @LiftedRep @a @a

is absolutely fine, because after we inline the unfolding, the \(x::a)
is representation-monomorphic.

Test cases: T14561, RepPolyWrappedVar2.

For primops (2) and unboxed tuples/sums (3), the situation is similar;
they are eta-expanded in CorePrep to be saturated, and that eta-expansion
must not add a representation-polymorphic lambda.

Test cases: T14561b, RepPolyWrappedVar, UnliftedNewtypesCoerceFail.

The Note [Representation-polymorphism checking built-ins] explains how we handle
cases (1) (2) and (3).

For (4), consider a representation-polymorphic newtype with
UnliftedNewtypes:

  type Id :: forall r. TYPE r -> TYPE r
  newtype Id a where { MkId :: a }

  bad :: forall r (a :: TYPE r). a -> Id a
  bad = MkId @r @a             -- Want to reject

  good :: forall (a :: Type). a -> Id a
  good = MkId @LiftedRep @a   -- Want to accept

Test cases: T18481, UnliftedNewtypesLevityBinder

(4) is handled differently than (1) (2) and (3);
see Note [Eta-expanding rep-poly unlifted newtypes].