This module exports some utility functions of no great interest.
\begin{code}
-#include "HsVersions.h"
-
module DsUtils (
CanItFail(..), EquationInfo(..), MatchResult(..),
- SYN_IE(EqnNo), SYN_IE(EqnSet),
+ EqnNo, EqnSet,
combineGRHSMatchResults,
combineMatchResults,
- dsExprToAtomGivenTy, SYN_IE(DsCoreArg),
+ dsExprToAtomGivenTy, DsCoreArg,
mkCoAlgCaseMatchResult,
mkAppDs, mkConDs, mkPrimDs, mkErrorAppDs,
mkCoLetsMatchResult,
mkFailurePair,
mkGuardedMatchResult,
mkSelectorBinds,
- mkTupleBind,
mkTupleExpr,
mkTupleSelector,
selectMatchVars,
showForErr
) where
-IMP_Ubiq()
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201
-IMPORT_DELOOPER(DsLoop) ( match, matchSimply )
-#else
-import {-# SOURCE #-} Match (match, matchSimply )
-#endif
+#include "HsVersions.h"
+
+import {-# SOURCE #-} Match ( matchSimply )
-import HsSyn ( HsExpr(..), OutPat(..), HsLit(..), Fixity,
- Match, HsBinds, Stmt, DoOrListComp, HsType, ArithSeqInfo )
-import TcHsSyn ( SYN_IE(TypecheckedPat) )
+import HsSyn ( OutPat(..), Stmt, DoOrListComp )
+import TcHsSyn ( TypecheckedPat )
import DsHsSyn ( outPatType, collectTypedPatBinders )
-import CmdLineOpts ( opt_PprUserLength )
import CoreSyn
import DsMonad
import CoreUtils ( coreExprType, mkCoreIfThenElse )
import PrelVals ( iRREFUT_PAT_ERROR_ID, voidId )
-import Pretty ( Doc, hcat, text )
import Id ( idType, dataConArgTys,
--- pprId{-ToDo:rm-},
- SYN_IE(DataCon), SYN_IE(DictVar), SYN_IE(Id), GenId )
+ DataCon, Id, GenId )
import Literal ( Literal(..) )
-import PprType ( GenType, GenTyVar )
import PrimOp ( PrimOp )
import TyCon ( isNewTyCon, tyConDataCons )
-import Type ( mkTyVarTys, mkRhoTy, mkForAllTys, mkFunTy,
- mkTheta, isUnboxedType, applyTyCon, getAppTyCon,
- GenType {- instances -}, SYN_IE(Type)
+import Type ( mkRhoTy, mkFunTy,
+ isUnpointedType, mkTyConApp, splitAlgTyConApp,
+ Type
)
-import TyVar ( GenTyVar {- instances -}, SYN_IE(TyVar) )
+import BasicTypes ( Unused )
import TysPrim ( voidTy )
-import TysWiredIn ( tupleTyCon, unitDataCon, tupleCon )
-import UniqSet ( mkUniqSet, minusUniqSet, uniqSetToList, SYN_IE(UniqSet) )
-import Util ( panic, assertPanic{-, pprTrace ToDo:rm-} )
+import TysWiredIn ( unitDataCon, tupleCon, stringTy )
+import UniqSet ( mkUniqSet, minusUniqSet, uniqSetToList, UniqSet )
import Unique ( Unique )
-import UniqSet
-import Usage ( SYN_IE(UVar) )
-import SrcLoc ( SrcLoc {- instance Outputable -} )
-
import Outputable
-
\end{code}
where
-- Common stuff
scrut_ty = idType var
- (tycon, tycon_arg_tys) = --pprTrace "CoAlgCase:" (pprType PprDebug scrut_ty) $
- getAppTyCon scrut_ty
+ (tycon, tycon_arg_tys, _) = splitAlgTyConApp scrut_ty
-- Stuff for newtype
(con_id, arg_ids, match_result) = head alts
arg_id = head arg_ids
- coercion_bind = NonRec arg_id (Coerce (CoerceOut con_id)
- (idType arg_id)
- (Var var))
+ coercion_bind = NonRec arg_id (Note (Coerce (idType arg_id) scrut_ty) (Var var))
newtype_sanity = null (tail alts) && null (tail arg_ids)
-- Stuff for data types
-- and delivering an expression E
-> DsM CoreExpr -- Either E or let x=arg-expr in E
-dsArgToAtom (UsageArg u) continue_with = continue_with (UsageArg u)
dsArgToAtom (TyArg t) continue_with = continue_with (TyArg t)
dsArgToAtom (LitArg l) continue_with = continue_with (LitArg l)
dsArgToAtom (VarArg arg) continue_with = dsExprToAtomGivenTy arg (coreExprType arg) continue_with
= newSysLocalDs arg_ty `thenDs` \ arg_id ->
continue_with (VarArg arg_id) `thenDs` \ body ->
returnDs (
- if isUnboxedType arg_ty
+ if isUnpointedType arg_ty
then Case arg_expr (PrimAlts [] (BindDefault arg_id body))
else Let (NonRec arg_id arg_expr) body
)
%************************************************************************
\begin{code}
-type DsCoreArg = GenCoreArg CoreExpr{-NB!-} TyVar UVar
+type DsCoreArg = GenCoreArg CoreExpr{-NB!-} Unused
mkAppDs :: CoreExpr -> [DsCoreArg] -> DsM CoreExpr
mkConDs :: Id -> [DsCoreArg] -> DsM CoreExpr
\begin{code}
showForErr :: Outputable a => a -> String -- Boring but useful
-showForErr thing = show (ppr PprQuote thing)
+showForErr thing = showSDoc (ppr thing)
mkErrorAppDs :: Id -- The error function
-> Type -- Type to which it should be applied
mkErrorAppDs err_id ty msg
= getSrcLocDs `thenDs` \ src_loc ->
let
- full_msg = show (hcat [ppr (PprForUser opt_PprUserLength) src_loc, text "|", text msg])
+ full_msg = showSDoc (hcat [ppr src_loc, text "|", text msg])
msg_lit = NoRepStr (_PK_ full_msg)
in
- returnDs (mkApp (Var err_id) [] [ty] [LitArg msg_lit])
+ returnDs (mkApp (Var err_id) [ty] [LitArg msg_lit])
\end{code}
%************************************************************************
= returnDs [(v, val_expr)]
mkSelectorBinds pat val_expr
- | is_simple_tuple_pat pat
- = mkTupleBind binders val_expr
-
- | otherwise
- = mkErrorAppDs iRREFUT_PAT_ERROR_ID res_ty pat_string `thenDs` \ error_expr ->
- matchSimply val_expr LetMatch pat res_ty local_tuple error_expr `thenDs` \ tuple_expr ->
- mkTupleBind binders tuple_expr
-
- where
- binders = collectTypedPatBinders pat
- local_tuple = mkTupleExpr binders
- res_ty = coreExprType local_tuple
-
- is_simple_tuple_pat (TuplePat ps) = all is_var_pat ps
- is_simple_tuple_pat other = False
-
- is_var_pat (VarPat v) = True
- is_var_pat other = False -- Even wild-card patterns aren't acceptable
-
- pat_string = show (ppr (PprForUser opt_PprUserLength) pat)
-\end{code}
-
-
-\begin{code}
-mkTupleBind :: [Id] -- Names of tuple components
- -> CoreExpr -- Expr whose value is a tuple of correct type
- -> DsM [(Id, CoreExpr)] -- Bindings for the globals
+ | length binders == 1 || is_simple_pat pat
+ = newSysLocalDs (coreExprType val_expr) `thenDs` \ val_var ->
+ -- For the error message we don't use mkErrorAppDs to avoid
+ -- duplicating the string literal each time
+ newSysLocalDs stringTy `thenDs` \ msg_var ->
+ getSrcLocDs `thenDs` \ src_loc ->
+ let
+ full_msg = showSDoc (hcat [ppr src_loc, text "|", ppr pat])
+ msg_lit = NoRepStr (_PK_ full_msg)
+ in
+ mapDs (mk_bind val_var msg_var) binders `thenDs` \ binds ->
+ returnDs ( (val_var, val_expr) :
+ (msg_var, Lit msg_lit) :
+ binds )
-mkTupleBind [local] tuple_expr
- = returnDs [(local, tuple_expr)]
-mkTupleBind locals tuple_expr
- = newSysLocalDs (coreExprType tuple_expr) `thenDs` \ tuple_var ->
+ | otherwise
+ = mkErrorAppDs iRREFUT_PAT_ERROR_ID tuple_ty (showSDoc (ppr pat)) `thenDs` \ error_expr ->
+ matchSimply val_expr LetMatch pat tuple_ty local_tuple error_expr `thenDs` \ tuple_expr ->
+ newSysLocalDs tuple_ty `thenDs` \ tuple_var ->
let
- mk_bind local = (local, mkTupleSelector locals local (Var tuple_var))
+ mk_tup_bind binder = (binder, mkTupleSelector binders binder (Var tuple_var))
in
- returnDs ( (tuple_var, tuple_expr) :
- map mk_bind locals )
+ returnDs ( (tuple_var, tuple_expr) : map mk_tup_bind binders )
+ where
+ binders = collectTypedPatBinders pat
+ local_tuple = mkTupleExpr binders
+ tuple_ty = coreExprType local_tuple
+
+ mk_bind scrut_var msg_var bndr_var
+ -- (mk_bind sv bv) generates
+ -- bv = case sv of { pat -> bv; other -> error-msg }
+ -- Remember, pat binds bv
+ = matchSimply (Var scrut_var) LetMatch pat binder_ty
+ (Var bndr_var) error_expr `thenDs` \ rhs_expr ->
+ returnDs (bndr_var, rhs_expr)
+ where
+ binder_ty = idType bndr_var
+ error_expr = mkApp (Var iRREFUT_PAT_ERROR_ID) [binder_ty] [VarArg msg_var]
+
+ is_simple_pat (TuplePat ps) = all is_triv_pat ps
+ is_simple_pat (ConPat _ _ ps) = all is_triv_pat ps
+ is_simple_pat (VarPat _) = True
+ is_simple_pat (ConOpPat p1 _ p2 _) = is_triv_pat p1 && is_triv_pat p2
+ is_simple_pat (RecPat _ _ ps) = and [is_triv_pat p | (_,p,_) <- ps]
+ is_simple_pat other = False
+
+ is_triv_pat (VarPat v) = True
+ is_triv_pat (WildPat _) = True
+ is_triv_pat other = False
\end{code}
@mkTupleExpr@ builds a tuple; the inverse to @mkTupleSelector@. If it
has only one element, it is the identity function.
+
\begin{code}
mkTupleExpr :: [Id] -> CoreExpr
mkTupleExpr [] = Con unitDataCon []
mkTupleExpr [id] = Var id
mkTupleExpr ids = mkCon (tupleCon (length ids))
- [{-usages-}]
(map idType ids)
[ VarArg i | i <- ids ]
\end{code}
-> CoreExpr -- Scrutinee
-> CoreExpr
-mkTupleSelector [] the_var scrut = panic "mkTupleSelector"
-
mkTupleSelector [var] should_be_the_same_var scrut
= ASSERT(var == should_be_the_same_var)
scrut
mkTupleSelector vars the_var scrut
- = Case scrut (AlgAlts [(tupleCon arity, vars, Var the_var)]
- NoDefault)
- where
- arity = length vars
+ = ASSERT( not (null vars) )
+ Case scrut (AlgAlts [(tupleCon (length vars), vars, Var the_var)] NoDefault)
\end{code}
CoreExpr) -- Either the fail variable, or fail variable
-- applied to unit tuple
mkFailurePair ty
- | isUnboxedType ty
+ | isUnpointedType ty
= newFailLocalDs (voidTy `mkFunTy` ty) `thenDs` \ fail_fun_var ->
newSysLocalDs voidTy `thenDs` \ fail_fun_arg ->
returnDs (\ body ->