+
+
+-- This rather ugly function converts the unpacked data con
+-- arguments back into their packed form.
+
+rebuildConArgs
+ :: [Id] -- Source-level args
+ -> [StrictnessMark] -- Strictness annotations (per-arg)
+ -> [Unique] -- Uniques for the new Ids
+ -> ([CoreBind], [Id]) -- A binding for each source-level arg, plus
+ -- a list of the representation-level arguments
+-- e.g. data T = MkT Int !Int
+--
+-- rebuild [x::Int, y::Int] [Not, Unbox]
+-- = ([ y = I# t ], [x,t])
+
+rebuildConArgs [] stricts us = ([], [])
+
+-- Type variable case
+rebuildConArgs (arg:args) stricts us
+ | isTyVar arg
+ = let (binds, args') = rebuildConArgs args stricts us
+ in (binds, arg:args')
+
+-- Term variable case
+rebuildConArgs (arg:args) (str:stricts) us
+ | isMarkedUnboxed str
+ = let
+ arg_ty = idType arg
+
+ (_, tycon_args, pack_con, con_arg_tys)
+ = splitProductType "rebuildConArgs" arg_ty
+
+ unpacked_args = zipWith (mkSysLocal SLIT("rb")) us con_arg_tys
+ (binds, args') = rebuildConArgs args stricts (drop (length con_arg_tys) us)
+ con_app = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args)
+ in
+ (NonRec arg con_app : binds, unpacked_args ++ args')
+
+ | otherwise
+ = let (binds, args') = rebuildConArgs args stricts us
+ in (binds, arg:args')