+tcDoStmt ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names
+ , recS_rec_ids = rec_names, recS_ret_fn = ret_op
+ , recS_mfix_fn = mfix_op, recS_bind_fn = bind_op })
+ res_ty thing_inside
+ = do { let tup_names = rec_names ++ filterOut (`elem` rec_names) later_names
+ ; tup_elt_tys <- newFlexiTyVarTys (length tup_names) liftedTypeKind
+ ; let tup_ids = zipWith mkLocalId tup_names tup_elt_tys
+ tup_ty = mkBoxedTupleTy tup_elt_tys
+
+ ; tcExtendIdEnv tup_ids $ do
+ { stmts_ty <- newFlexiTyVarTy liftedTypeKind
+ ; (stmts', (ret_op', tup_rets))
+ <- tcStmts ctxt tcDoStmt stmts stmts_ty $ \ inner_res_ty ->
+ do { tup_rets <- zipWithM tcCheckId tup_names tup_elt_tys
+ -- Unify the types of the "final" Ids (which may
+ -- be polymorphic) with those of "knot-tied" Ids
+ ; ret_op' <- tcSyntaxOp DoOrigin ret_op (mkFunTy tup_ty inner_res_ty)
+ ; return (ret_op', tup_rets) }
+
+ ; mfix_res_ty <- newFlexiTyVarTy liftedTypeKind
+ ; mfix_op' <- tcSyntaxOp DoOrigin mfix_op
+ (mkFunTy (mkFunTy tup_ty stmts_ty) mfix_res_ty)
+
+ ; new_res_ty <- newFlexiTyVarTy liftedTypeKind
+ ; bind_op' <- tcSyntaxOp DoOrigin bind_op
+ (mkFunTys [mfix_res_ty, mkFunTy tup_ty new_res_ty] res_ty)
+
+ ; thing <- thing_inside new_res_ty
+-- ; lie_binds <- bindLocalMethods lie tup_ids
+
+ ; let rec_ids = takeList rec_names tup_ids
+ ; later_ids <- tcLookupLocalIds later_names
+ ; traceTc "tcdo" $ vcat [ppr rec_ids <+> ppr (map idType rec_ids),
+ ppr later_ids <+> ppr (map idType later_ids)]
+ ; return (RecStmt { recS_stmts = stmts', recS_later_ids = later_ids
+ , recS_rec_ids = rec_ids, recS_ret_fn = ret_op'
+ , recS_mfix_fn = mfix_op', recS_bind_fn = bind_op'
+ , recS_rec_rets = tup_rets, recS_dicts = emptyTcEvBinds }, thing)
+ }}