+
+
+-- this rather ugly function converts the unpacked data con arguments back into
+-- their packed form. It is almost the same as the version in DsUtils, except that
+-- we use template locals here rather than newDsId (ToDo: merge these).
+
+rebuildConArgs
+ :: DataCon -- the con we're matching on
+ -> [Id] -- the source-level args
+ -> [StrictnessMark] -- the strictness annotations (per-arg)
+ -> CoreExpr -- the body
+ -> Int -- template local
+ -> (CoreExpr, [Id])
+
+rebuildConArgs con [] stricts body i = (body, [])
+rebuildConArgs con (arg:args) stricts body i | isTyVar arg
+ = let (body', args') = rebuildConArgs con args stricts body i
+ in (body',arg:args')
+rebuildConArgs con (arg:args) (str:stricts) body i
+ = case maybeMarkedUnboxed str of
+ Just (pack_con1, _) ->
+ case splitProductType_maybe (idType arg) of
+ Just (_, tycon_args, pack_con, con_arg_tys) ->
+ ASSERT( pack_con == pack_con1 )
+ let unpacked_args = zipWith mkTemplateLocal [i..] con_arg_tys
+ (body', real_args) = rebuildConArgs con args stricts body
+ (i + length con_arg_tys)
+ in
+ (
+ Let (NonRec arg (mkConApp pack_con
+ (map Type tycon_args ++
+ map Var unpacked_args))) body',
+ unpacked_args ++ real_args
+ )
+
+ _ -> let (body', args') = rebuildConArgs con args stricts body i
+ in (body', arg:args')