Skip to content

isLiftedType_maybe is wrong for type families

In compiler/GHC/Core/Type.hs, there's

-- | Returns Just True if this type is surely lifted, Just False
-- if it is surely unlifted, Nothing if we can't be sure (i.e., it is
-- representation-polymorphic), and panics if the kind does not have the shape
-- TYPE r.
isLiftedType_maybe :: HasDebugCallStack => Type -> Maybe Bool
isLiftedType_maybe ty = case coreFullView (getRuntimeRep ty) of
  ty' | isLiftedRuntimeRep ty'  -> Just True
  TyConApp {}                   -> Just False  -- Everything else is unlifted
  _                             -> Nothing     -- representation-polymorphic

This was meant to return "definitely unlifted" for IntRep, AddrRep etc., but it also incorrectly returns "definitely unlifted" for type families. Compare with isUnliftedRuntimeRep, which returns a definitive answer only if the datacon satisfies isPromotedDataCon.

I attempted to fix this in wip/isliftedtype, commit 56e041bb. However, this uncovered another problem. I ran tests in rep-poly and I got failures in T20363, RepPolyBackpack2, RepPolyBackpack4. I investigated only the first one, the Backpack tests should be similar.

The test T20363 uses a type T :: TYPE R (where R is a type family reducing to a definite RuntimeRep). It passes the new representation polymorphism checks in the typechecker, and later in the pipeline calls to isUnliftedType T cause a panic because isLiftedType_maybe T is now Nothing.

I think the proper fix would be to reject T20363 until we have phase 2 of FixedRuntimeRep. I don't know how to do that though.

cc @sheaf

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information