+
+%************************************************************************
+%* *
+\subsection{dsLet}
+%* *
+%************************************************************************
+
+@dsLet@ is a match-result transformer, taking the MatchResult for the body
+and transforming it into one for the let-bindings enclosing the body.
+
+This may seem a bit odd, but (source) let bindings can contain unboxed
+binds like
+
+ C x# = e
+
+This must be transformed to a case expression and, if the type has
+more than one constructor, may fail.
+
+\begin{code}
+dsLet :: TypecheckedHsBinds -> CoreExpr -> DsM CoreExpr
+
+dsLet EmptyBinds body
+ = returnDs body
+
+dsLet (ThenBinds b1 b2) body
+ = dsLet b2 body `thenDs` \ body' ->
+ dsLet b1 body'
+
+-- Special case for bindings which bind unlifted variables
+dsLet (MonoBind (AbsBinds [] [] binder_triples (PatMonoBind pat grhss loc)) sigs is_rec) body
+ | or [isUnLiftedType (idType g) | (_, g, l) <- binder_triples]
+ = ASSERT (case is_rec of {NonRecursive -> True; other -> False})
+ putSrcLocDs loc $
+ dsGuarded grhss `thenDs` \ rhs ->
+ let
+ body' = foldr bind body binder_triples
+ bind (tyvars, g, l) body = ASSERT( null tyvars )
+ bindNonRec g (Var l) body
+ in
+ mkErrorAppDs iRREFUT_PAT_ERROR_ID result_ty (showSDoc (ppr pat)) `thenDs` \ error_expr ->
+ matchSimply rhs PatBindMatch pat body' error_expr
+ where
+ result_ty = coreExprType body
+
+-- Ordinary case for bindings
+dsLet (MonoBind binds sigs is_rec) body
+ = dsMonoBinds False binds [] `thenDs` \ prs ->
+ case is_rec of
+ Recursive -> returnDs (Let (Rec prs) body)
+ NonRecursive -> returnDs (foldr mk_let body prs)
+ where
+ mk_let (bndr,rhs) body = Let (NonRec bndr rhs) body
+\end{code}