It makes *sense* for a foreign import to have a zero-sized return, thus
foreign import ccall foo :: Int -> State# RealWorld
but it's not clear that it's useful, and it requires some back-end (a
Hint for void types) to make it go right through. It's not clear that
we really want this facility, so rather than fixing the code
generator, I'm just making the construct illegal for now.
-- it no longer does so. May need to adjust isFFIDotNetTy
-- if we do want to look through newtypes.
-- it no longer does so. May need to adjust isFFIDotNetTy
-- if we do want to look through newtypes.
-isFFIDotnetObjTy ty =
- let
+isFFIDotnetObjTy ty
+ = checkRepTyCon check_tc t_ty
+ where
(_, t_ty) = tcSplitForAllTys ty
(_, t_ty) = tcSplitForAllTys ty
- in
- case tcSplitTyConApp_maybe (repType t_ty) of
- Just (tc, [arg_ty]) | getName tc == objectTyConName -> True
- _ -> False
+ check_tc tc = getName tc == objectTyConName
toDNType :: Type -> DNType
toDNType ty
toDNType :: Type -> DNType
toDNType ty
= isUnLiftedTyCon tc || boxedMarshalableTyCon tc || tc == unitTyCon
marshalableTyCon dflags tc
= isUnLiftedTyCon tc || boxedMarshalableTyCon tc || tc == unitTyCon
marshalableTyCon dflags tc
- = (dopt Opt_UnliftedFFITypes dflags && isUnLiftedTyCon tc)
+ = (dopt Opt_UnliftedFFITypes dflags
+ && isUnLiftedTyCon tc
+ && case tyConPrimRep tc of -- Note [Marshalling VoidRep]
+ VoidRep -> False
+ other -> True)
|| boxedMarshalableTyCon tc
boxedMarshalableTyCon tc
|| boxedMarshalableTyCon tc
boxedMarshalableTyCon tc
, boolTyConKey
]
\end{code}
, boolTyConKey
]
\end{code}
+
+Note [Marshalling VoidRep]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+We don't treat State# (whose PrimRep is VoidRep) as marshalable.
+In turn that means you can't write
+ foreign import foo :: Int -> State# RealWorld
+
+Reason: the back end falls over with panic "primRepHint:VoidRep";
+ and there is no compelling reason to permit it