summaryrefslogtreecommitdiff
path: root/ghc/compiler/deSugar
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/compiler/deSugar')
-rw-r--r--ghc/compiler/deSugar/Desugar.lhs59
-rw-r--r--ghc/compiler/deSugar/DsBinds.lhs123
-rw-r--r--ghc/compiler/deSugar/DsExpr.lhs144
-rw-r--r--ghc/compiler/deSugar/DsGRHSs.lhs6
-rw-r--r--ghc/compiler/deSugar/DsHsSyn.lhs1
-rw-r--r--ghc/compiler/deSugar/DsListComp.lhs150
-rw-r--r--ghc/compiler/deSugar/DsLoop.lhi2
-rw-r--r--ghc/compiler/deSugar/DsMonad.lhs51
-rw-r--r--ghc/compiler/deSugar/DsUtils.lhs19
-rw-r--r--ghc/compiler/deSugar/Match.lhs74
-rw-r--r--ghc/compiler/deSugar/MatchLit.lhs70
11 files changed, 393 insertions, 306 deletions
diff --git a/ghc/compiler/deSugar/Desugar.lhs b/ghc/compiler/deSugar/Desugar.lhs
index 697c32dd2f..40e3bcc1fc 100644
--- a/ghc/compiler/deSugar/Desugar.lhs
+++ b/ghc/compiler/deSugar/Desugar.lhs
@@ -6,23 +6,28 @@
\begin{code}
#include "HsVersions.h"
-module Desugar ( deSugar, DsMatchContext, pprDsWarnings ) where
+module Desugar ( deSugar, DsMatchContext, pprDsWarnings,
+ DsWarnFlavour -- removed when compiling with 1.4
+ ) where
IMP_Ubiq(){-uitous-}
import HsSyn ( HsBinds, HsExpr )
import TcHsSyn ( SYN_IE(TypecheckedHsBinds), SYN_IE(TypecheckedHsExpr) )
import CoreSyn
-
+import Name ( isExported )
import DsMonad
import DsBinds ( dsBinds, dsInstBinds )
import DsUtils
import Bag ( unionBags )
-import CmdLineOpts ( opt_DoCoreLinting, opt_AutoSccsOnAllToplevs, opt_AutoSccsOnExportedToplevs )
+import CmdLineOpts ( opt_DoCoreLinting, opt_AutoSccsOnAllToplevs,
+ opt_AutoSccsOnExportedToplevs, opt_SccGroup
+ )
+import CostCentre ( IsCafCC(..), mkAutoCC )
import CoreLift ( liftCoreBindings )
import CoreLint ( lintCoreBindings )
-import Id ( nullIdEnv, mkIdEnv )
+import Id ( nullIdEnv, mkIdEnv, idType, SYN_IE(DictVar), GenId )
import PprStyle ( PprStyle(..) )
import UniqSupply ( splitUniqSupply )
\end{code}
@@ -42,7 +47,7 @@ deSugar :: UniqSupply -- name supply
-- ToDo: handling of const_inst thingies is certainly WRONG ***************************
-> ([CoreBinding], -- output
- Bag DsMatchContext) -- Shadowing complaints
+ DsWarnings) -- Shadowing complaints
deSugar us mod_name (recsel_binds, clas_binds, inst_binds, val_binds, const_inst_pairs)
= let
@@ -52,9 +57,11 @@ deSugar us mod_name (recsel_binds, clas_binds, inst_binds, val_binds, const_inst
(us3, us3a) = splitUniqSupply us2a
(us4, us5) = splitUniqSupply us3a
- auto_meth = opt_AutoSccsOnAllToplevs
- auto_top = opt_AutoSccsOnAllToplevs
- || opt_AutoSccsOnExportedToplevs
+
+ module_and_group = (mod_name, grp_name)
+ grp_name = case opt_SccGroup of
+ Just xx -> _PK_ xx
+ Nothing -> mod_name -- default: module name
((core_const_prs, consts_pairs), shadows1)
= initDs us0 nullIdEnv mod_name (dsInstBinds [] const_inst_pairs)
@@ -62,19 +69,19 @@ deSugar us mod_name (recsel_binds, clas_binds, inst_binds, val_binds, const_inst
consts_env = mkIdEnv consts_pairs
(core_clas_binds, shadows2)
- = initDs us1 consts_env mod_name (dsBinds False clas_binds)
+ = initDs us1 consts_env mod_name (dsBinds clas_binds)
core_clas_prs = pairsFromCoreBinds core_clas_binds
(core_inst_binds, shadows3)
- = initDs us2 consts_env mod_name (dsBinds auto_meth inst_binds)
+ = initDs us2 consts_env mod_name (dsBinds inst_binds)
core_inst_prs = pairsFromCoreBinds core_inst_binds
(core_val_binds, shadows4)
- = initDs us3 consts_env mod_name (dsBinds auto_top val_binds)
- core_val_pairs = pairsFromCoreBinds core_val_binds
+ = initDs us3 consts_env mod_name (dsBinds val_binds)
+ core_val_pairs = map (addAutoScc module_and_group) (pairsFromCoreBinds core_val_binds)
(core_recsel_binds, shadows5)
- = initDs us4 consts_env mod_name (dsBinds ({-trace "Desugar:core_recsel_binds"-} False) recsel_binds)
+ = initDs us4 consts_env mod_name (dsBinds recsel_binds)
core_recsel_prs = pairsFromCoreBinds core_recsel_binds
final_binds
@@ -98,3 +105,29 @@ deSugar us mod_name (recsel_binds, clas_binds, inst_binds, val_binds, const_inst
in
(really_final_binds, shadows)
\end{code}
+
+
+%************************************************************************
+%* *
+\subsection[addAutoScc]{Adding automatic sccs}
+%* *
+%************************************************************************
+
+\begin{code}
+addAutoScc :: (FAST_STRING, FAST_STRING) -- Module and group
+ -> (Id, CoreExpr)
+ -> (Id,CoreExpr)
+
+addAutoScc (mod, grp) pair@(bndr, core_expr)
+ | worthSCC core_expr &&
+ (opt_AutoSccsOnAllToplevs ||
+ (isExported bndr && opt_AutoSccsOnExportedToplevs))
+ = (bndr, SCC (mkAutoCC bndr mod grp IsNotCafCC) core_expr)
+
+ | otherwise
+ = pair
+
+worthSCC (SCC _ _) = False
+worthSCC (Con _ _) = False
+worthSCC core_expr = True
+\end{code}
diff --git a/ghc/compiler/deSugar/DsBinds.lhs b/ghc/compiler/deSugar/DsBinds.lhs
index 657e2652f1..af09307aba 100644
--- a/ghc/compiler/deSugar/DsBinds.lhs
+++ b/ghc/compiler/deSugar/DsBinds.lhs
@@ -29,7 +29,8 @@ import DsGRHSs ( dsGuarded )
import DsUtils
import Match ( matchWrapper )
-import CmdLineOpts ( opt_SccProfilingOn, opt_AutoSccsOnAllToplevs, opt_CompilingGhcInternals )
+import CmdLineOpts ( opt_SccProfilingOn, opt_AutoSccsOnAllToplevs,
+ opt_AutoSccsOnExportedToplevs, opt_CompilingGhcInternals )
import CostCentre ( mkAutoCC, IsCafCC(..), mkAllDictsCC, preludeDictsCostCentre )
import Id ( idType, SYN_IE(DictVar), GenId )
import ListSetOps ( minusList, intersectLists )
@@ -59,7 +60,7 @@ that some of the binders are of unboxed type. This is sorted out when
the caller wraps the bindings round an expression.
\begin{code}
-dsBinds :: Bool -> TypecheckedHsBinds -> DsM [CoreBinding]
+dsBinds :: TypecheckedHsBinds -> DsM [CoreBinding]
\end{code}
All ``real'' bindings are expressed in terms of the
@@ -95,12 +96,12 @@ But there are lots of special cases.
%==============================================
\begin{code}
-dsBinds auto_scc (BindWith _ _) = panic "dsBinds:BindWith"
-dsBinds auto_scc EmptyBinds = returnDs []
-dsBinds auto_scc (SingleBind bind) = dsBind auto_scc [] [] id [] bind
+dsBinds (BindWith _ _) = panic "dsBinds:BindWith"
+dsBinds EmptyBinds = returnDs []
+dsBinds (SingleBind bind) = dsBind [] [] id [] bind
-dsBinds auto_scc (ThenBinds binds_1 binds_2)
- = andDs (++) (dsBinds auto_scc binds_1) (dsBinds auto_scc binds_2)
+dsBinds (ThenBinds binds_1 binds_2)
+ = andDs (++) (dsBinds binds_1) (dsBinds binds_2)
\end{code}
@@ -129,7 +130,7 @@ definitions, which don't mention the type variables at all, so making them
polymorphic is really overkill. @dsInstBinds@ deals with this case.
\begin{code}
-dsBinds auto_scc (AbsBinds tyvars [] local_global_prs inst_binds val_binds)
+dsBinds (AbsBinds tyvars [] local_global_prs inst_binds val_binds)
= mapDs mk_poly_private_binder private_binders
`thenDs` \ poly_private_binders ->
let
@@ -148,7 +149,7 @@ dsBinds auto_scc (AbsBinds tyvars [] local_global_prs inst_binds val_binds)
dsInstBinds tyvars inst_binds `thenDs` \ (inst_bind_pairs, inst_env) ->
extendEnvDs inst_env (
- dsBind auto_scc tyvars [] (lookupId full_local_global_prs) inst_bind_pairs val_binds
+ dsBind tyvars [] (lookupId full_local_global_prs) inst_bind_pairs val_binds
))
where
-- "private_binders" is the list of binders in val_binds
@@ -194,7 +195,7 @@ the defn of f' can get floated out, notably if f gets specialised
to a particular type for a.
\begin{code}
-dsBinds auto_scc (AbsBinds all_tyvars dicts local_global_prs dict_binds val_binds)
+dsBinds (AbsBinds all_tyvars dicts local_global_prs dict_binds val_binds)
= -- If there is any non-overloaded polymorphism, make new locals with
-- appropriate polymorphism
(if null non_overloaded_tyvars
@@ -230,7 +231,7 @@ dsBinds auto_scc (AbsBinds all_tyvars dicts local_global_prs dict_binds val_bind
extendEnvDs inst_env (
- dsBind auto_scc non_overloaded_tyvars [] binder_subst_fn inst_bind_pairs val_binds
+ dsBind non_overloaded_tyvars [] binder_subst_fn inst_bind_pairs val_binds
)) `thenDs` \ core_binds ->
let
@@ -240,7 +241,7 @@ dsBinds auto_scc (AbsBinds all_tyvars dicts local_global_prs dict_binds val_bind
in
mkTupleBind all_tyvars dicts local_global_prs tuple_rhs `thenDs` \ core_bind_prs ->
- returnDs [ NonRec binder rhs | (binder,rhs) <- core_bind_prs ]
+ returnDs (mk_result_bind core_bind_prs)
where
locals = [local | (local,global) <- local_global_prs]
non_ov_tyvar_tys = mkTyVarTys non_overloaded_tyvars
@@ -250,6 +251,14 @@ dsBinds auto_scc (AbsBinds all_tyvars dicts local_global_prs dict_binds val_bind
binders = collectTypedBinders val_binds
mk_binder id = newSysLocalDs (mkForAllTys non_overloaded_tyvars (idType id))
+
+ is_rec_bind = case val_binds of
+ RecBind _ -> True
+ NonRecBind _ -> False
+
+ -- Recursion can still be needed if there are type signatures
+ mk_result_bind prs | is_rec_bind = [Rec prs]
+ | otherwise = [NonRec binder rhs | (binder,rhs) <- prs]
\end{code}
@mkSatTyApp id tys@ constructs an expression whose value is (id tys).
@@ -385,22 +394,21 @@ some of the binders are of unboxed type.
For an explanation of the first three args, see @dsMonoBinds@.
\begin{code}
-dsBind :: Bool -- Add auto sccs to binds
- -> [TyVar] -> [DictVar] -- Abstract wrt these
+dsBind :: [TyVar] -> [DictVar] -- Abstract wrt these
-> (Id -> Id) -- Binder substitution
-> [(Id,CoreExpr)] -- Inst bindings already dealt with
-> TypecheckedBind
-> DsM [CoreBinding]
-dsBind auto_scc tyvars dicts binder_subst inst_bind_pairs EmptyBind
+dsBind tyvars dicts binder_subst inst_bind_pairs EmptyBind
= returnDs [NonRec binder rhs | (binder,rhs) <- inst_bind_pairs]
-dsBind auto_scc tyvars dicts binder_subst inst_bind_pairs (NonRecBind monobinds)
- = dsMonoBinds auto_scc False tyvars dicts binder_subst monobinds `thenDs` \ val_bind_pairs ->
+dsBind tyvars dicts binder_subst inst_bind_pairs (NonRecBind monobinds)
+ = dsMonoBinds False tyvars dicts binder_subst monobinds `thenDs` \ val_bind_pairs ->
returnDs [NonRec binder rhs | (binder,rhs) <- inst_bind_pairs ++ val_bind_pairs]
-dsBind auto_scc tyvars dicts binder_subst inst_bind_pairs (RecBind monobinds)
- = dsMonoBinds auto_scc True tyvars dicts binder_subst monobinds `thenDs` \ val_bind_pairs ->
+dsBind tyvars dicts binder_subst inst_bind_pairs (RecBind monobinds)
+ = dsMonoBinds True tyvars dicts binder_subst monobinds `thenDs` \ val_bind_pairs ->
returnDs [Rec (inst_bind_pairs ++ val_bind_pairs)]
\end{code}
@@ -424,8 +432,7 @@ of these binders into applications of the new binder to suitable type variables
and dictionaries.
\begin{code}
-dsMonoBinds :: Bool -- True <=> add auto sccs
- -> Bool -- True <=> recursive binding group
+dsMonoBinds :: Bool -- True <=> recursive binding group
-> [TyVar] -> [DictVar] -- Abstract wrt these
-> (Id -> Id) -- Binder substitution
-> TypecheckedMonoBinds
@@ -439,11 +446,11 @@ dsMonoBinds :: Bool -- True <=> add auto sccs
%==============================================
\begin{code}
-dsMonoBinds auto_scc is_rec tyvars dicts binder_subst EmptyMonoBinds = returnDs []
+dsMonoBinds is_rec tyvars dicts binder_subst EmptyMonoBinds = returnDs []
-dsMonoBinds auto_scc is_rec tyvars dicts binder_subst (AndMonoBinds binds_1 binds_2)
- = andDs (++) (dsMonoBinds auto_scc is_rec tyvars dicts binder_subst binds_1)
- (dsMonoBinds auto_scc is_rec tyvars dicts binder_subst binds_2)
+dsMonoBinds is_rec tyvars dicts binder_subst (AndMonoBinds binds_1 binds_2)
+ = andDs (++) (dsMonoBinds is_rec tyvars dicts binder_subst binds_1)
+ (dsMonoBinds is_rec tyvars dicts binder_subst binds_2)
\end{code}
@@ -452,31 +459,27 @@ dsMonoBinds auto_scc is_rec tyvars dicts binder_subst (AndMonoBinds binds_1 bin
%==============================================
\begin{code}
-dsMonoBinds auto_scc is_rec tyvars dicts binder_subst (CoreMonoBind var core_expr)
- = doSccAuto auto_scc [var] core_expr `thenDs` \ sccd_core_expr ->
- returnDs [(binder_subst var, mkLam tyvars dicts sccd_core_expr)]
+dsMonoBinds is_rec tyvars dicts binder_subst (CoreMonoBind var core_expr)
+ = returnDs [(binder_subst var, mkLam tyvars dicts core_expr)]
-dsMonoBinds auto_scc is_rec tyvars dicts binder_subst (VarMonoBind var expr)
+dsMonoBinds is_rec tyvars dicts binder_subst (VarMonoBind var expr)
= dsExpr expr `thenDs` \ core_expr ->
- doSccAuto auto_scc [var] core_expr `thenDs` \ sccd_core_expr ->
- returnDs [(binder_subst var, mkLam tyvars dicts sccd_core_expr)]
+ returnDs [(binder_subst var, mkLam tyvars dicts core_expr)]
-dsMonoBinds auto_scc is_rec tyvars dicts binder_subst (FunMonoBind fun _ matches locn)
+dsMonoBinds is_rec tyvars dicts binder_subst (FunMonoBind fun _ matches locn)
= putSrcLocDs locn $
let
new_fun = binder_subst fun
error_string = "function " ++ showForErr fun
in
matchWrapper (FunMatch fun) matches error_string `thenDs` \ (args, body) ->
- doSccAuto auto_scc [fun] body `thenDs` \ sccd_body ->
returnDs [(new_fun,
- mkLam tyvars (dicts ++ args) sccd_body)]
+ mkLam tyvars (dicts ++ args) body)]
-dsMonoBinds auto_scc is_rec tyvars dicts binder_subst (PatMonoBind (VarPat v) grhss_and_binds locn)
+dsMonoBinds is_rec tyvars dicts binder_subst (PatMonoBind (VarPat v) grhss_and_binds locn)
= putSrcLocDs locn $
dsGuarded grhss_and_binds `thenDs` \ body_expr ->
- doSccAuto auto_scc [v] body_expr `thenDs` \ sccd_body_expr ->
- returnDs [(binder_subst v, mkLam tyvars dicts sccd_body_expr)]
+ returnDs [(binder_subst v, mkLam tyvars dicts body_expr)]
\end{code}
%==============================================
@@ -490,7 +493,7 @@ be empty. (Simple pattern bindings were handled above.)
First, the paranoia check.
\begin{code}
-dsMonoBinds auto_scc is_rec tyvars (_:_) binder_subst (PatMonoBind pat grhss_and_binds locn)
+dsMonoBinds is_rec tyvars (_:_) binder_subst (PatMonoBind pat grhss_and_binds locn)
= panic "Non-empty dict list in for pattern binding"
\end{code}
@@ -518,11 +521,10 @@ Then we transform to:
\end{description}
\begin{code}
-dsMonoBinds auto_scc is_rec tyvars [] binder_subst (PatMonoBind pat grhss_and_binds locn)
+dsMonoBinds is_rec tyvars [] binder_subst (PatMonoBind pat grhss_and_binds locn)
= putSrcLocDs locn $
dsGuarded grhss_and_binds `thenDs` \ body_expr ->
- doSccAuto auto_scc pat_binders body_expr `thenDs` \ sccd_body_expr ->
{- KILLED by Sansom. 95/05
-- make *sure* there are no primitive types in the pattern
@@ -535,11 +537,11 @@ dsMonoBinds auto_scc is_rec tyvars [] binder_subst (PatMonoBind pat grhss_and_bi
-- we can just use the rhs directly
else
-}
--- pprTrace "dsMonoBinds:PatMonoBind:" (ppr PprDebug sccd_body_expr) $
+-- pprTrace "dsMonoBinds:PatMonoBind:" (ppr PprDebug body_expr) $
mkSelectorBinds tyvars pat
[(binder, binder_subst binder) | binder <- pat_binders]
- sccd_body_expr
+ body_expr
where
pat_binders = collectTypedPatBinders pat
-- NB For a simple tuple pattern, these binders
@@ -552,40 +554,3 @@ extra work to benefit only rather unusual constructs like
let (_,a,b) = ... in ...
\end{verbatim}
Better to extend the whole thing for any irrefutable constructor, at least.
-
-%************************************************************************
-%* *
-\subsection[doSccAuto]{Adding automatic sccs}
-%* *
-%************************************************************************
-
-\begin{code}
-doSccAuto :: Bool -> [Id] -> CoreExpr -> DsM CoreExpr
-
-doSccAuto False binders core_expr
- = returnDs core_expr
-
-doSccAuto True [] core_expr -- no binders
- = returnDs core_expr
-
-doSccAuto True _ core_expr@(SCC _ _) -- already sccd
- = returnDs core_expr
-
-doSccAuto True _ core_expr@(Con _ _) -- dont bother for simple Con
- = returnDs core_expr
-
-doSccAuto True binders core_expr
- = let
- scc_all = opt_AutoSccsOnAllToplevs
- scc_export = not (null export_binders)
-
- export_binders = filter isExported binders
-
- scc_binder = head (if scc_all then binders else export_binders)
- in
- if scc_all || scc_export then
- getModuleAndGroupDs `thenDs` \ (mod,grp) ->
- returnDs (SCC (mkAutoCC scc_binder mod grp IsNotCafCC) core_expr)
- else
- returnDs core_expr
-\end{code}
diff --git a/ghc/compiler/deSugar/DsExpr.lhs b/ghc/compiler/deSugar/DsExpr.lhs
index 2efca382c9..96e870e4e8 100644
--- a/ghc/compiler/deSugar/DsExpr.lhs
+++ b/ghc/compiler/deSugar/DsExpr.lhs
@@ -13,7 +13,7 @@ IMPORT_DELOOPER(DsLoop) -- partly to get dsBinds, partly to chk dsExpr
import HsSyn ( failureFreePat,
HsExpr(..), OutPat(..), HsLit(..), ArithSeqInfo(..),
- Stmt(..), Match(..), Qualifier, HsBinds, HsType, Fixity,
+ Stmt(..), DoOrListComp(..), Match(..), HsBinds, HsType, Fixity,
GRHSsAndBinds
)
import TcHsSyn ( SYN_IE(TypecheckedHsExpr), SYN_IE(TypecheckedHsBinds),
@@ -47,16 +47,17 @@ import PprType ( GenType )
import PrelVals ( rEC_CON_ERROR_ID, rEC_UPD_ERROR_ID, voidId )
import Pretty ( ppShow, ppBesides, ppPStr, ppStr )
import TyCon ( isDataTyCon, isNewTyCon )
-import Type ( splitSigmaTy, splitFunTy, typePrimRep,
- getAppDataTyConExpandingDicts, getAppTyCon, applyTy,
- maybeBoxedPrimType
+import Type ( splitSigmaTy, splitFunTy, typePrimRep,
+ getAppDataTyConExpandingDicts, maybeAppTyCon, getAppTyCon, applyTy,
+ maybeBoxedPrimType, splitAppTy
)
import TysPrim ( voidTy )
-import TysWiredIn ( mkTupleTy, tupleCon, nilDataCon, consDataCon,
+import TysWiredIn ( mkTupleTy, tupleCon, nilDataCon, consDataCon, listTyCon,
charDataCon, charTy
)
import TyVar ( nullTyVarEnv, addOneToTyVarEnv, GenTyVar{-instance Eq-} )
import Usage ( SYN_IE(UVar) )
+import Maybes ( maybeToBool )
import Util ( zipEqual, pprError, panic, assertPanic )
mk_nil_con ty = mkCon nilDataCon [] [ty] [] -- micro utility...
@@ -75,7 +76,7 @@ around; if we get hits, we use the value accordingly.
\begin{code}
dsExpr :: TypecheckedHsExpr -> DsM CoreExpr
-dsExpr e@(HsVar var) = dsApp e []
+dsExpr e@(HsVar var) = dsId var
\end{code}
%************************************************************************
@@ -261,18 +262,25 @@ dsExpr expr@(HsCase discrim matches src_loc)
matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
returnDs ( mkCoLetAny (NonRec discrim_var core_discrim) matching_code )
-dsExpr (ListComp expr quals)
- = dsExpr expr `thenDs` \ core_expr ->
- dsListComp core_expr quals
-
dsExpr (HsLet binds expr)
- = dsBinds False binds `thenDs` \ core_binds ->
+ = dsBinds binds `thenDs` \ core_binds ->
dsExpr expr `thenDs` \ core_expr ->
returnDs ( mkCoLetsAny core_binds core_expr )
-dsExpr (HsDoOut stmts then_id zero_id src_loc)
+dsExpr (HsDoOut do_or_lc stmts return_id then_id zero_id result_ty src_loc)
+ | maybeToBool maybe_list_comp -- Special case for list comprehensions
+ = putSrcLocDs src_loc $
+ dsListComp stmts elt_ty
+
+ | otherwise
= putSrcLocDs src_loc $
- dsDo then_id zero_id stmts
+ dsDo do_or_lc stmts return_id then_id zero_id result_ty
+ where
+ maybe_list_comp = case maybeAppTyCon result_ty of
+ Just (tycon, [elt_ty]) | tycon == listTyCon
+ -> Just elt_ty
+ other -> Nothing
+ Just elt_ty = maybe_list_comp
dsExpr (HsIf guard_expr then_expr else_expr src_loc)
= putSrcLocDs src_loc $
@@ -519,7 +527,7 @@ dsExpr (ClassDictLam dicts methods expr)
#ifdef DEBUG
-- HsSyn constructs that just shouldn't be here:
-dsExpr (HsDo _ _) = panic "dsExpr:HsDo"
+dsExpr (HsDo _ _ _) = panic "dsExpr:HsDo"
dsExpr (ExplicitList _) = panic "dsExpr:ExplicitList"
dsExpr (ExprWithTySig _ _) = panic "dsExpr:ExprWithTySig"
dsExpr (ArithSeqIn _) = panic "dsExpr:ArithSeqIn"
@@ -565,13 +573,13 @@ dsApp (TyApp expr tys) args
-- we might should look out for SectionLs, etc., here, but we don't
-dsApp (HsVar v) args
- = lookupEnvDs v `thenDs` \ maybe_expr ->
- mkAppDs (case maybe_expr of { Nothing -> Var v; Just expr -> expr }) args
-
dsApp anything_else args
= dsExpr anything_else `thenDs` \ core_expr ->
mkAppDs core_expr args
+
+dsId v
+ = lookupEnvDs v `thenDs` \ maybe_expr ->
+ returnDs (case maybe_expr of { Nothing -> Var v; Just expr -> expr })
\end{code}
\begin{code}
@@ -611,47 +619,73 @@ dsRbinds ((sel_id, rhs, pun_flag) : rbinds) continue_with
Basically does the translation given in the Haskell~1.3 report:
\begin{code}
-dsDo :: Id -- id for: (>>=) m
- -> Id -- id for: zero m
+dsDo :: DoOrListComp
-> [TypecheckedStmt]
+ -> Id -- id for: return m
+ -> Id -- id for: (>>=) m
+ -> Id -- id for: zero m
+ -> Type -- Element type; the whole expression has type (m t)
-> DsM CoreExpr
-dsDo then_id zero_id (stmt:stmts)
- = case stmt of
- ExprStmt expr locn -> ASSERT( null stmts ) do_expr expr locn
-
- ExprStmtOut expr locn a b ->
- do_expr expr locn `thenDs` \ expr2 ->
- ds_rest `thenDs` \ rest ->
- newSysLocalDs a `thenDs` \ ignored_result_id ->
- dsApp (HsVar then_id) [TyArg a, TyArg b, VarArg expr2,
- VarArg (mkValLam [ignored_result_id] rest)]
-
- LetStmt binds ->
- dsBinds False binds `thenDs` \ binds2 ->
- ds_rest `thenDs` \ rest ->
- returnDs (mkCoLetsAny binds2 rest)
-
- BindStmtOut pat expr locn a b ->
- do_expr expr locn `thenDs` \ expr2 ->
- let
- zero_expr = TyApp (HsVar zero_id) [b]
- main_match
- = PatMatch pat (SimpleMatch (HsDoOut stmts then_id zero_id locn))
- the_matches
- = if failureFreePat pat
- then [main_match]
- else [main_match, PatMatch (WildPat a) (SimpleMatch zero_expr)]
- in
- matchWrapper DoBindMatch the_matches "`do' statement"
- `thenDs` \ (binders, matching_code) ->
- dsApp (HsVar then_id) [TyArg a, TyArg b,
- VarArg expr2, VarArg (mkValLam binders matching_code)]
+dsDo do_or_lc stmts return_id then_id zero_id result_ty
+ = dsId return_id `thenDs` \ return_ds ->
+ dsId then_id `thenDs` \ then_ds ->
+ dsId zero_id `thenDs` \ zero_ds ->
+ let
+ (_, b_ty) = splitAppTy result_ty -- result_ty must be of the form (m b)
+
+ go [ReturnStmt expr]
+ = dsExpr expr `thenDs` \ expr2 ->
+ mkAppDs return_ds [TyArg b_ty, VarArg expr2]
+
+ go (GuardStmt expr locn : stmts)
+ = do_expr expr locn `thenDs` \ expr2 ->
+ go stmts `thenDs` \ rest ->
+ mkAppDs zero_ds [TyArg b_ty] `thenDs` \ zero_expr ->
+ returnDs (mkCoreIfThenElse expr2 rest zero_expr)
+
+ go (ExprStmt expr locn : stmts)
+ = do_expr expr locn `thenDs` \ expr2 ->
+ let
+ (_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
+ in
+ if null stmts then
+ returnDs expr2
+ else
+ go stmts `thenDs` \ rest ->
+ newSysLocalDs a_ty `thenDs` \ ignored_result_id ->
+ mkAppDs then_ds [TyArg a_ty, TyArg b_ty, VarArg expr2,
+ VarArg (mkValLam [ignored_result_id] rest)]
+
+ go (LetStmt binds : stmts )
+ = dsBinds binds `thenDs` \ binds2 ->
+ go stmts `thenDs` \ rest ->
+ returnDs (mkCoLetsAny binds2 rest)
+
+ go (BindStmt pat expr locn : stmts)
+ = putSrcLocDs locn $
+ dsExpr expr `thenDs` \ expr2 ->
+ let
+ (_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
+ zero_expr = TyApp (HsVar zero_id) [b_ty]
+ main_match = PatMatch pat (SimpleMatch (
+ HsDoOut do_or_lc stmts return_id then_id zero_id result_ty locn))
+ the_matches
+ = if failureFreePat pat
+ then [main_match]
+ else [main_match, PatMatch (WildPat a_ty) (SimpleMatch zero_expr)]
+ in
+ matchWrapper DoBindMatch the_matches match_msg
+ `thenDs` \ (binders, matching_code) ->
+ mkAppDs then_ds [TyArg a_ty, TyArg b_ty,
+ VarArg expr2, VarArg (mkValLam binders matching_code)]
+ in
+ go stmts
+
where
- ds_rest = dsDo then_id zero_id stmts
do_expr expr locn = putSrcLocDs locn (dsExpr expr)
-#ifdef DEBUG
-dsDo then_expr zero_expr [] = panic "dsDo:[]"
-#endif
+ match_msg = case do_or_lc of
+ DoStmt -> "`do' statement"
+ ListComp -> "comprehension"
\end{code}
diff --git a/ghc/compiler/deSugar/DsGRHSs.lhs b/ghc/compiler/deSugar/DsGRHSs.lhs
index 6b95110a28..c36e0bd58b 100644
--- a/ghc/compiler/deSugar/DsGRHSs.lhs
+++ b/ghc/compiler/deSugar/DsGRHSs.lhs
@@ -12,7 +12,8 @@ IMP_Ubiq()
IMPORT_DELOOPER(DsLoop) -- break dsExpr/dsBinds-ish loop
import HsSyn ( GRHSsAndBinds(..), GRHS(..),
- HsExpr, HsBinds )
+ HsExpr, HsBinds
+ )
import TcHsSyn ( SYN_IE(TypecheckedGRHSsAndBinds), SYN_IE(TypecheckedGRHS),
SYN_IE(TypecheckedPat), SYN_IE(TypecheckedHsBinds),
SYN_IE(TypecheckedHsExpr) )
@@ -45,7 +46,7 @@ dsGuarded :: TypecheckedGRHSsAndBinds
-> DsM CoreExpr
dsGuarded (GRHSsAndBindsOut grhss binds err_ty)
- = dsBinds False binds `thenDs` \ core_binds ->
+ = dsBinds binds `thenDs` \ core_binds ->
dsGRHSs err_ty PatBindMatch [] grhss `thenDs` \ (MatchResult can_it_fail _ core_grhss_fn _) ->
case can_it_fail of
CantFail -> returnDs (mkCoLetsAny core_binds (core_grhss_fn (panic "It can't fail")))
@@ -96,3 +97,4 @@ dsGRHS ty kind pats (GRHS guard expr locn)
\end{code}
+
diff --git a/ghc/compiler/deSugar/DsHsSyn.lhs b/ghc/compiler/deSugar/DsHsSyn.lhs
index d7e54ef40a..010d741291 100644
--- a/ghc/compiler/deSugar/DsHsSyn.lhs
+++ b/ghc/compiler/deSugar/DsHsSyn.lhs
@@ -36,6 +36,7 @@ outPatType (TuplePat pats) = mkTupleTy (length pats) (map outPatType pats)
outPatType (RecPat _ ty _) = ty
outPatType (LitPat lit ty) = ty
outPatType (NPat lit ty _) = ty
+outPatType (NPlusKPat _ _ ty _ _) = ty
outPatType (DictPat ds ms) = case (length ds_ms) of
0 -> unitTy
1 -> idType (head ds_ms)
diff --git a/ghc/compiler/deSugar/DsListComp.lhs b/ghc/compiler/deSugar/DsListComp.lhs
index 2a396ea7eb..bec2c8ac24 100644
--- a/ghc/compiler/deSugar/DsListComp.lhs
+++ b/ghc/compiler/deSugar/DsListComp.lhs
@@ -11,8 +11,8 @@ module DsListComp ( dsListComp ) where
IMP_Ubiq()
IMPORT_DELOOPER(DsLoop) -- break dsExpr-ish loop
-import HsSyn ( Qualifier(..), HsExpr, HsBinds )
-import TcHsSyn ( SYN_IE(TypecheckedQual), SYN_IE(TypecheckedHsExpr) , SYN_IE(TypecheckedHsBinds) )
+import HsSyn ( Stmt(..), HsExpr, HsBinds )
+import TcHsSyn ( SYN_IE(TypecheckedStmt), SYN_IE(TypecheckedHsExpr) , SYN_IE(TypecheckedHsBinds) )
import DsHsSyn ( outPatType )
import CoreSyn
@@ -37,42 +37,36 @@ turned on'' (if you read Gill {\em et al.}'s paper on the subject).
There will be at least one ``qualifier'' in the input.
\begin{code}
-dsListComp :: CoreExpr -> [TypecheckedQual] -> DsM CoreExpr
+dsListComp :: [TypecheckedStmt]
+ -> Type -- Type of list elements
+ -> DsM CoreExpr
+
+dsListComp quals elt_ty
+ | not opt_FoldrBuildOn -- Be boring
+ = deListComp quals nil_expr
-dsListComp expr quals
- = let
- expr_ty = coreExprType expr
+ | otherwise -- foldr/build lives!
+ = newTyVarsDs [alphaTyVar] `thenDs` \ [n_tyvar] ->
+ let
+ alpha_to_alpha = alphaTy `mkFunTy` alphaTy
+
+ n_ty = mkTyVarTy n_tyvar
+ c_ty = mkFunTys [elt_ty, n_ty] n_ty
+ g_ty = mkForAllTy alphaTyVar (
+ (elt_ty `mkFunTy` alpha_to_alpha)
+ `mkFunTy`
+ alpha_to_alpha
+ )
in
- if not opt_FoldrBuildOn then -- be boring
- deListComp expr quals (nIL_EXPR expr_ty)
-
- else -- foldr/build lives!
- new_alpha_tyvar `thenDs` \ (n_tyvar, n_ty) ->
- let
- alpha_to_alpha = alphaTy `mkFunTy` alphaTy
-
- c_ty = mkFunTys [expr_ty, n_ty] n_ty
- g_ty = mkForAllTy alphaTyVar (
- (expr_ty `mkFunTy` alpha_to_alpha)
- `mkFunTy`
- alpha_to_alpha
- )
- in
- newSysLocalsDs [c_ty,n_ty,g_ty] `thenDs` \ [c, n, g] ->
-
- dfListComp expr expr_ty
- c_ty c
- n_ty n
- quals `thenDs` \ result ->
-
- returnDs (mkBuild expr_ty n_tyvar c n g result)
- where
- nIL_EXPR ty = mkCon nilDataCon [] [ty] []
+ newSysLocalsDs [c_ty,n_ty,g_ty] `thenDs` \ [c, n, g] ->
- new_alpha_tyvar :: DsM (TyVar, Type)
- new_alpha_tyvar
- = newTyVarsDs [alphaTyVar] `thenDs` \ [new_ty] ->
- returnDs (new_ty, mkTyVarTy new_ty)
+ dfListComp c_ty c
+ n_ty n
+ quals `thenDs` \ result ->
+
+ returnDs (mkBuild elt_ty n_tyvar c n g result)
+ where
+ nil_expr = mkCon nilDataCon [] [elt_ty] []
\end{code}
%************************************************************************
@@ -119,23 +113,24 @@ is the TE translation scheme. Note that we carry around the @L@ list
already desugared. @dsListComp@ does the top TE rule mentioned above.
\begin{code}
-deListComp :: CoreExpr -> [TypecheckedQual] -> CoreExpr -> DsM CoreExpr
+deListComp :: [TypecheckedStmt] -> CoreExpr -> DsM CoreExpr
-deListComp expr [] list -- Figure 7.4, SLPJ, p 135, rule C above
- = mkConDs consDataCon [TyArg (coreExprType expr), VarArg expr, VarArg list]
+deListComp [ReturnStmt expr] list -- Figure 7.4, SLPJ, p 135, rule C above
+ = dsExpr expr `thenDs` \ core_expr ->
+ mkConDs consDataCon [TyArg (coreExprType core_expr), VarArg core_expr, VarArg list]
-deListComp expr (FilterQual filt : quals) list -- rule B above
- = dsExpr filt `thenDs` \ core_filt ->
- deListComp expr quals list `thenDs` \ core_rest ->
- returnDs ( mkCoreIfThenElse core_filt core_rest list )
+deListComp (GuardStmt guard locn : quals) list -- rule B above
+ = dsExpr guard `thenDs` \ core_guard ->
+ deListComp quals list `thenDs` \ core_rest ->
+ returnDs (mkCoreIfThenElse core_guard core_rest list)
-- [e | let B, qs] = let B in [e | qs]
-deListComp expr (LetQual binds : quals) list
- = dsBinds False binds `thenDs` \ core_binds ->
- deListComp expr quals list `thenDs` \ core_rest ->
+deListComp (LetStmt binds : quals) list
+ = dsBinds binds `thenDs` \ core_binds ->
+ deListComp quals list `thenDs` \ core_rest ->
returnDs (mkCoLetsAny core_binds core_rest)
-deListComp expr ((GeneratorQual pat list1):quals) core_list2 -- rule A' above
+deListComp (BindStmt pat list1 locn : quals) core_list2 -- rule A' above
= dsExpr list1 `thenDs` \ core_list1 ->
let
u3_ty@u1_ty = coreExprType core_list1 -- two names, same thing
@@ -146,27 +141,14 @@ deListComp expr ((GeneratorQual pat list1):quals) core_list2 -- rule A' above
res_ty = coreExprType core_list2
h_ty = u1_ty `mkFunTy` res_ty
in
- newSysLocalsDs [h_ty, u1_ty, u2_ty, u3_ty]
- `thenDs` \ [h', u1, u2, u3] ->
- {-
- Make the function h unfoldable by the deforester.
- Since it only occurs once in the body, we can't get
- an increase in code size by unfolding it.
- -}
- let
- h = if False -- LATER: sw_chkr DoDeforest???
- then panic "deListComp:deforest"
- -- replaceIdInfo h' (addInfo (getIdInfo h') DoDeforest)
- else h'
- in
- -- the "fail" value ...
- mkAppDs (Var h) [VarArg (Var u3)] `thenDs` \ core_fail ->
-
- deListComp expr quals core_fail `thenDs` \ rest_expr ->
+ newSysLocalsDs [h_ty, u1_ty, u2_ty, u3_ty] `thenDs` \ [h, u1, u2, u3] ->
- matchSimply (Var u2) pat res_ty rest_expr core_fail `thenDs` \ core_match ->
-
- mkAppDs (Var h) [VarArg core_list1] `thenDs` \ letrec_body ->
+ -- the "fail" value ...
+ mkAppDs (Var h) [VarArg (Var u3)] `thenDs` \ core_fail ->
+ deListComp quals core_fail `thenDs` \ rest_expr ->
+ matchSimply (Var u2) pat res_ty
+ rest_expr core_fail `thenDs` \ core_match ->
+ mkAppDs (Var h) [VarArg core_list1] `thenDs` \ letrec_body ->
returnDs (
mkCoLetrecAny [
@@ -174,8 +156,8 @@ deListComp expr ((GeneratorQual pat list1):quals) core_list2 -- rule A' above
(Lam (ValBinder u1)
(Case (Var u1)
(AlgAlts
- [(nilDataCon, [], core_list2),
- (consDataCon, [u2, u3], core_match)]
+ [(nilDataCon, [], core_list2),
+ (consDataCon, [u2, u3], core_match)]
NoDefault)))
)] letrec_body
)
@@ -196,29 +178,27 @@ TE << [ e | p <- l , q ] c n = foldr
_ b -> b) n l
\end{verbatim}
\begin{code}
-dfListComp :: CoreExpr -- the inside of the comp
- -> Type -- the type of the inside
- -> Type -> Id -- 'c'; its type and id
+dfListComp :: Type -> Id -- 'c'; its type and id
-> Type -> Id -- 'n'; its type and id
- -> [TypecheckedQual] -- the rest of the qual's
+ -> [TypecheckedStmt] -- the rest of the qual's
-> DsM CoreExpr
-dfListComp expr expr_ty c_ty c_id n_ty n_id []
- = mkAppDs (Var c_id) [VarArg expr, VarArg (Var n_id)]
+dfListComp c_ty c_id n_ty n_id [ReturnStmt expr]
+ = dsExpr expr `thenDs` \ core_expr ->
+ mkAppDs (Var c_id) [VarArg core_expr, VarArg (Var n_id)]
-dfListComp expr expr_ty c_ty c_id n_ty n_id (FilterQual filt : quals)
- = dsExpr filt `thenDs` \ core_filt ->
- dfListComp expr expr_ty c_ty c_id n_ty n_id quals
- `thenDs` \ core_rest ->
- returnDs (mkCoreIfThenElse core_filt core_rest (Var n_id))
+dfListComp c_ty c_id n_ty n_id (GuardStmt guard locn : quals)
+ = dsExpr guard `thenDs` \ core_guard ->
+ dfListComp c_ty c_id n_ty n_id quals `thenDs` \ core_rest ->
+ returnDs (mkCoreIfThenElse core_guard core_rest (Var n_id))
-dfListComp expr expr_ty c_ty c_id n_ty n_id (LetQual binds : quals)
+dfListComp c_ty c_id n_ty n_id (LetStmt binds : quals)
-- new in 1.3, local bindings
- = dsBinds False binds `thenDs` \ core_binds ->
- dfListComp expr expr_ty c_ty c_id n_ty n_id quals `thenDs` \ core_rest ->
- returnDs ( mkCoLetsAny core_binds core_rest )
+ = dsBinds binds `thenDs` \ core_binds ->
+ dfListComp c_ty c_id n_ty n_id quals `thenDs` \ core_rest ->
+ returnDs (mkCoLetsAny core_binds core_rest)
-dfListComp expr expr_ty c_ty c_id n_ty n_id (GeneratorQual pat list1 : quals)
+dfListComp c_ty c_id n_ty n_id (BindStmt pat list1 locn : quals)
-- evaluate the two lists
= dsExpr list1 `thenDs` \ core_list1 ->
@@ -236,7 +216,7 @@ dfListComp expr expr_ty c_ty c_id n_ty n_id (GeneratorQual pat list1 : quals)
-- build rest of the comprehesion
- dfListComp expr expr_ty c_ty c_id b_ty b quals `thenDs` \ core_rest ->
+ dfListComp c_ty c_id b_ty b quals `thenDs` \ core_rest ->
-- build the pattern match
matchSimply (Var p) pat b_ty core_rest (Var b) `thenDs` \ core_expr ->
diff --git a/ghc/compiler/deSugar/DsLoop.lhi b/ghc/compiler/deSugar/DsLoop.lhi
index fd329c0c69..26a0c4b313 100644
--- a/ghc/compiler/deSugar/DsLoop.lhi
+++ b/ghc/compiler/deSugar/DsLoop.lhi
@@ -26,6 +26,6 @@ matchSimply :: CoreExpr -- Scrutinee
-> CoreExpr -- Return this if it does
-> DsM CoreExpr
-dsBinds :: Bool -> TypecheckedHsBinds -> DsM [CoreBinding]
+dsBinds :: TypecheckedHsBinds -> DsM [CoreBinding]
dsExpr :: TypecheckedHsExpr -> DsM CoreExpr
\end{code}
diff --git a/ghc/compiler/deSugar/DsMonad.lhs b/ghc/compiler/deSugar/DsMonad.lhs
index bf3f5f0878..38e567a7ea 100644
--- a/ghc/compiler/deSugar/DsMonad.lhs
+++ b/ghc/compiler/deSugar/DsMonad.lhs
@@ -20,8 +20,11 @@ module DsMonad (
SYN_IE(DsIdEnv),
lookupId,
- dsShadowError,
- DsMatchContext(..), DsMatchKind(..), pprDsWarnings
+ dsShadowWarn, dsIncompleteWarn,
+ DsWarnings(..),
+ DsMatchContext(..), DsMatchKind(..), pprDsWarnings,
+ DsWarnFlavour -- Nuke with 1.4
+
) where
IMP_Ubiq()
@@ -60,8 +63,9 @@ type DsM result =
-> DsWarnings
-> (result, DsWarnings)
-type DsWarnings = Bag DsMatchContext -- The desugarer reports matches which are
- -- completely shadowed
+type DsWarnings = Bag (DsWarnFlavour, DsMatchContext)
+ -- The desugarer reports matches which are
+ -- completely shadowed or incomplete patterns
{-# INLINE andDs #-}
{-# INLINE thenDs #-}
{-# INLINE returnDs #-}
@@ -181,9 +185,13 @@ putSrcLocDs :: SrcLoc -> DsM a -> DsM a
putSrcLocDs new_loc expr us old_loc mod_and_grp env warns
= expr us new_loc mod_and_grp env warns
-dsShadowError :: DsMatchContext -> DsM ()
-dsShadowError cxt us loc mod_and_grp env warns
- = ((), warns `snocBag` cxt)
+dsShadowWarn :: DsMatchContext -> DsM ()
+dsShadowWarn cxt us loc mod_and_grp env warns
+ = ((), warns `snocBag` (Shadowed, cxt))
+
+dsIncompleteWarn :: DsMatchContext -> DsM ()
+dsIncompleteWarn cxt us loc mod_and_grp env warns
+ = ((), warns `snocBag` (Incomplete, cxt))
\end{code}
\begin{code}
@@ -237,9 +245,12 @@ lookupId env id
%************************************************************************
\begin{code}
+data DsWarnFlavour = Shadowed | Incomplete deriving ()
+
data DsMatchContext
= DsMatchContext DsMatchKind [TypecheckedPat] SrcLoc
| NoMatchContext
+ deriving ()
data DsMatchKind
= FunMatch Id
@@ -247,23 +258,31 @@ data DsMatchKind
| LambdaMatch
| PatBindMatch
| DoBindMatch
+ deriving ()
-pprDsWarnings :: PprStyle -> Bag DsMatchContext -> Pretty
+pprDsWarnings :: PprStyle -> DsWarnings -> Pretty
pprDsWarnings sty warns
- = ppAboves (map pp_cxt (bagToList warns))
+ = ppAboves (map pp_warn (bagToList warns))
where
- pp_cxt NoMatchContext = ppPStr SLIT("Some match is shadowed; I don't know what")
- pp_cxt (DsMatchContext kind pats loc)
- = ppHang (ppBesides [ppr PprForUser loc, ppPStr SLIT(": ")])
- 4 (ppHang (ppPStr SLIT("Pattern match(es) completely overlapped:"))
+ pp_warn (flavour, NoMatchContext) = ppSep [ppPStr SLIT("Warning: Some match is"),
+ case flavour of
+ Shadowed -> ppPStr SLIT("shadowed")
+ Incomplete -> ppPStr SLIT("possibly incomplete")]
+
+ pp_warn (flavour, DsMatchContext kind pats loc)
+ = ppHang (ppBesides [ppr PprForUser loc, ppPStr SLIT(": ")])
+ 4 (ppHang msg
4 (pp_match kind pats))
+ where
+ msg = case flavour of
+ Shadowed -> ppPStr SLIT("Warning: Pattern match(es) completely overlapped")
+ Incomplete -> ppPStr SLIT("Warning: Possibly incomplete patterns")
pp_match (FunMatch fun) pats
- = ppHang (ppr sty fun)
- 4 (ppSep [ppSep (map (ppr sty) pats), ppPStr SLIT("= ...")])
+ = ppCat [ppPStr SLIT("in the definition of function"), ppQuote (ppr sty fun)]
pp_match CaseMatch pats
- = ppHang (ppPStr SLIT("in a case alternative:"))
+ = ppHang (ppPStr SLIT("in a group of case alternative beginning:"))
4 (ppSep [ppSep (map (ppr sty) pats), pp_arrow_dotdotdot])
pp_match PatBindMatch pats
diff --git a/ghc/compiler/deSugar/DsUtils.lhs b/ghc/compiler/deSugar/DsUtils.lhs
index ff2ec5fe45..3fdc1d3c9a 100644
--- a/ghc/compiler/deSugar/DsUtils.lhs
+++ b/ghc/compiler/deSugar/DsUtils.lhs
@@ -31,7 +31,7 @@ IMP_Ubiq()
IMPORT_DELOOPER(DsLoop) ( match, matchSimply )
import HsSyn ( HsExpr(..), OutPat(..), HsLit(..), Fixity,
- Match, HsBinds, Stmt, Qualifier, HsType, ArithSeqInfo )
+ Match, HsBinds, Stmt, DoOrListComp, HsType, ArithSeqInfo )
import TcHsSyn ( SYN_IE(TypecheckedPat) )
import DsHsSyn ( outPatType )
import CoreSyn
@@ -46,21 +46,20 @@ import Id ( idType, dataConArgTys,
-- pprId{-ToDo:rm-},
SYN_IE(DataCon), SYN_IE(DictVar), SYN_IE(Id), GenId )
import Literal ( Literal(..) )
+import PprType ( GenType, GenTyVar )
import TyCon ( isNewTyCon, tyConDataCons )
import Type ( mkTyVarTys, mkRhoTy, mkForAllTys, mkFunTy,
- mkTheta, isUnboxedType, applyTyCon, getAppTyCon
+ mkTheta, isUnboxedType, applyTyCon, getAppTyCon,
+ GenType {- instances -}
)
+import TyVar ( GenTyVar {- instances -} )
import TysPrim ( voidTy )
import TysWiredIn ( tupleTyCon, unitDataCon, tupleCon )
import UniqSet ( mkUniqSet, minusUniqSet, uniqSetToList, SYN_IE(UniqSet) )
import Util ( panic, assertPanic{-, pprTrace ToDo:rm-} )
+import Unique ( Unique )
import Usage ( SYN_IE(UVar) )
import SrcLoc ( SrcLoc {- instance Outputable -} )
---import PprCore{-ToDo:rm-}
---import PprType--ToDo:rm
---import Pretty--ToDo:rm
---import TyVar--ToDo:rm
---import Unique--ToDo:rm
\end{code}
%************************************************************************
@@ -316,7 +315,7 @@ mkErrorAppDs :: Id -- The error function
mkErrorAppDs err_id ty msg
= getSrcLocDs `thenDs` \ src_loc ->
let
- full_msg = ppShow 80 (ppBesides [ppr PprForUser src_loc, ppStr ": ", ppStr msg])
+ full_msg = ppShow 80 (ppBesides [ppr PprForUser src_loc, ppStr "|", ppStr msg])
msg_lit = NoRepStr (_PK_ full_msg)
in
returnDs (mkApp (Var err_id) [] [ty] [LitArg msg_lit])
@@ -356,7 +355,7 @@ mkSelectorBinds tyvars pat locals_and_globals val_expr
= if is_simple_tuple_pat pat then
mkTupleBind tyvars [] locals_and_globals val_expr
else
- mkErrorAppDs iRREFUT_PAT_ERROR_ID res_ty "" `thenDs` \ error_msg ->
+ mkErrorAppDs iRREFUT_PAT_ERROR_ID res_ty pat_string `thenDs` \ error_msg ->
matchSimply val_expr pat res_ty local_tuple error_msg `thenDs` \ tuple_expr ->
mkTupleBind tyvars [] locals_and_globals tuple_expr
where
@@ -369,6 +368,8 @@ mkSelectorBinds tyvars pat locals_and_globals val_expr
is_var_pat (VarPat v) = True
is_var_pat other = False -- Even wild-card patterns aren't acceptable
+
+ pat_string = ppShow 80 (ppr PprForUser pat)
\end{code}
We're about to match against some patterns. We want to make some
diff --git a/ghc/compiler/deSugar/Match.lhs b/ghc/compiler/deSugar/Match.lhs
index c822765110..7fb28b1c05 100644
--- a/ghc/compiler/deSugar/Match.lhs
+++ b/ghc/compiler/deSugar/Match.lhs
@@ -153,31 +153,27 @@ And gluing the ``success expressions'' together isn't quite so pretty.
\begin{code}
match [] eqns_info shadows
- = pin_eqns eqns_info `thenDs` \ match_result@(MatchResult _ _ _ cxt) ->
+ = complete_matches eqns_info (any eqn_cant_fail shadows)
+ where
+ complete_matches [eqn] is_shadowed
+ = complete_match eqn is_shadowed
+
+ complete_matches (eqn:eqns) is_shadowed
+ = complete_match eqn is_shadowed `thenDs` \ match_result1 ->
+ complete_matches eqns (is_shadowed || eqn_cant_fail eqn) `thenDs` \ match_result2 ->
+ combineMatchResults match_result1 match_result2
-- If at this stage we find that at least one of the shadowing
-- equations is guaranteed not to fail, then warn of an overlapping pattern
- if not (all shadow_can_fail shadows) then
- dsShadowError cxt `thenDs` \ _ ->
- returnDs match_result
- else
- returnDs match_result
-
- where
- pin_eqns [EqnInfo [] match_result] = returnDs match_result
- -- Last eqn... can't have pats ...
-
- pin_eqns (EqnInfo [] match_result1 : more_eqns)
- = pin_eqns more_eqns `thenDs` \ match_result2 ->
- combineMatchResults match_result1 match_result2
+ complete_match (EqnInfo [] match_result@(MatchResult _ _ _ cxt)) is_shadowed
+ | is_shadowed = dsShadowWarn cxt `thenDs` \ _ ->
+ returnDs match_result
- pin_eqns other_pat = panic "match: pin_eqns"
+ | otherwise = returnDs match_result
- shadow_can_fail :: EquationInfo -> Bool
-
- shadow_can_fail (EqnInfo [] (MatchResult CanFail _ _ _)) = True
- shadow_can_fail (EqnInfo [] (MatchResult CantFail _ _ _)) = False
- shadow_can_fail other = panic "match:shadow_can_fail"
+ eqn_cant_fail :: EquationInfo -> Bool
+ eqn_cant_fail (EqnInfo [] (MatchResult CanFail _ _ _)) = False
+ eqn_cant_fail (EqnInfo [] (MatchResult CantFail _ _ _)) = True
\end{code}
%************************************************************************
@@ -253,6 +249,8 @@ Replace the `as' pattern @x@@p@ with the pattern p and a binding @x = v@.
Removing lazy (irrefutable) patterns (you don't want to know...).
\item
Converting explicit tuple- and list-pats into ordinary @ConPats@.
+\item
+Convert the literal pat "" to [].
\end{itemize}
The result of this tidying is that the column of patterns will include
@@ -395,6 +393,7 @@ tidy1 v pat@(LitPat lit lit_ty) match_result
-- NPats: we *might* be able to replace these w/ a simpler form
+
tidy1 v pat@(NPat lit lit_ty _) match_result
= returnDs (better_pat, match_result)
where
@@ -405,6 +404,10 @@ tidy1 v pat@(NPat lit lit_ty _) match_result
| lit_ty `eqTy` addrTy = ConPat addrDataCon lit_ty [LitPat (mk_addr lit) addrPrimTy]
| lit_ty `eqTy` floatTy = ConPat floatDataCon lit_ty [LitPat (mk_float lit) floatPrimTy]
| lit_ty `eqTy` doubleTy = ConPat doubleDataCon lit_ty [LitPat (mk_double lit) doublePrimTy]
+
+ -- Convert the literal pattern "" to the constructor pattern [].
+ | null_str_lit lit = ConPat nilDataCon lit_ty []
+
| otherwise = pat
mk_int (HsInt i) = HsIntPrim i
@@ -425,6 +428,9 @@ tidy1 v pat@(NPat lit lit_ty _) match_result
mk_double (HsFrac f) = HsDoublePrim f
mk_double l@(HsLitLit s) = l
+ null_str_lit (HsString s) = _NULL_ s
+ null_str_lit other_lit = False
+
-- and everything else goes through unchanged...
tidy1 v non_interesting_pat match_result
@@ -608,7 +614,7 @@ matchWrapper kind [(PatMatch (WildPat ty) match)] error_string
matchWrapper kind [(GRHSMatch
(GRHSsAndBindsOut [OtherwiseGRHS expr _] binds _))] error_string
- = dsBinds False binds `thenDs` \ core_binds ->
+ = dsBinds binds `thenDs` \ core_binds ->
dsExpr expr `thenDs` \ core_expr ->
returnDs ([], mkCoLetsAny core_binds core_expr)
@@ -622,8 +628,14 @@ matchWrapper kind matches error_string
match new_vars eqns_info [] `thenDs` \ match_result ->
mkErrorAppDs pAT_ERROR_ID result_ty error_string `thenDs` \ fail_expr ->
- extractMatchResult match_result fail_expr `thenDs` \ result_expr ->
+ -- Check for incomplete pattern match
+ (case match_result of
+ MatchResult CanFail result_ty match_fn cxt -> dsIncompleteWarn cxt
+ other -> returnDs ()
+ ) `thenDs` \ _ ->
+
+ extractMatchResult match_result fail_expr `thenDs` \ result_expr ->
returnDs (new_vars, result_expr)
\end{code}
@@ -664,8 +676,8 @@ matchSimply scrut_expr pat result_ty result_expr msg
extractMatchResult (MatchResult CantFail _ match_fn _) fail_expr
= returnDs (match_fn (error "It can't fail!"))
-extractMatchResult (MatchResult CanFail result_ty match_fn _) fail_expr
- = mkFailurePair result_ty `thenDs` \ (fail_bind_fn, if_it_fails) ->
+extractMatchResult (MatchResult CanFail result_ty match_fn cxt) fail_expr
+ = mkFailurePair result_ty `thenDs` \ (fail_bind_fn, if_it_fails) ->
returnDs (Let (fail_bind_fn fail_expr) (match_fn if_it_fails))
\end{code}
@@ -699,7 +711,7 @@ flattenMatches kind (match : matches)
= flatten_match (pat:pats_so_far) match
flatten_match pats_so_far (GRHSMatch (GRHSsAndBindsOut grhss binds ty))
- = dsBinds False binds `thenDs` \ core_binds ->
+ = dsBinds binds `thenDs` \ core_binds ->
dsGRHSs ty kind pats grhss `thenDs` \ match_result ->
returnDs (EqnInfo pats (mkCoLetsMatchResult core_binds match_result))
where
@@ -707,12 +719,14 @@ flattenMatches kind (match : matches)
flatten_match pats_so_far (SimpleMatch expr)
= dsExpr expr `thenDs` \ core_expr ->
+ getSrcLocDs `thenDs` \ locn ->
returnDs (EqnInfo pats
(MatchResult CantFail (coreExprType core_expr)
(\ ignore -> core_expr)
- NoMatchContext))
- -- The NoMatchContext is just a place holder. In a simple match,
- -- the matching can't fail, so we won't generate an error message.
- where
- pats = reverse pats_so_far -- They've accumulated in reverse order
+ (DsMatchContext kind pats locn)))
+
+ -- the matching can't fail, so we won't generate an error message.
+ where
+ pats = reverse pats_so_far -- They've accumulated in reverse order
+
\end{code}
diff --git a/ghc/compiler/deSugar/MatchLit.lhs b/ghc/compiler/deSugar/MatchLit.lhs
index a4ed52d685..c7e4bc1d9c 100644
--- a/ghc/compiler/deSugar/MatchLit.lhs
+++ b/ghc/compiler/deSugar/MatchLit.lhs
@@ -12,11 +12,12 @@ IMP_Ubiq()
IMPORT_DELOOPER(DsLoop) -- break match-ish and dsExpr-ish loops
import HsSyn ( HsLit(..), OutPat(..), HsExpr(..), Fixity,
- Match, HsBinds, Stmt, Qualifier, HsType, ArithSeqInfo )
+ Match, HsBinds, Stmt(..), DoOrListComp, HsType, ArithSeqInfo )
import TcHsSyn ( SYN_IE(TypecheckedHsExpr), SYN_IE(TypecheckedHsBinds),
SYN_IE(TypecheckedPat)
)
-import CoreSyn ( SYN_IE(CoreExpr), SYN_IE(CoreBinding) )
+import CoreSyn ( SYN_IE(CoreExpr), SYN_IE(CoreBinding), GenCoreExpr(..), GenCoreBinding(..) )
+import Id ( GenId {- instance Eq -} )
import DsMonad
import DsUtils
@@ -54,9 +55,9 @@ matchLiterals all_vars@(var:vars) eqns_info@(EqnInfo (LitPat literal lit_ty : ps
match_prims_used vars eqns_info@(EqnInfo ((LitPat literal lit_ty):ps1) _ : eqns) shadows
= let
(shifted_eqns_for_this_lit, eqns_not_for_this_lit)
- = partitionEqnsByLit literal eqns_info
+ = partitionEqnsByLit Nothing literal eqns_info
(shifted_shadows_for_this_lit, shadows_not_for_this_lit)
- = partitionEqnsByLit literal shadows
+ = partitionEqnsByLit Nothing literal shadows
in
-- recursive call to make other alts...
match_prims_used vars eqns_not_for_this_lit shadows_not_for_this_lit `thenDs` \ rest_of_alts ->
@@ -85,9 +86,9 @@ matchLiterals all_vars@(var:vars) eqns_info@(EqnInfo (LitPat literal lit_ty : ps
matchLiterals all_vars@(var:vars) eqns_info@(EqnInfo ((NPat literal lit_ty eq_chk):ps1) _ : eqns) shadows
= let
(shifted_eqns_for_this_lit, eqns_not_for_this_lit)
- = partitionEqnsByLit literal eqns_info
+ = partitionEqnsByLit Nothing literal eqns_info
(shifted_shadows_for_this_lit, shadows_not_for_this_lit)
- = partitionEqnsByLit literal shadows
+ = partitionEqnsByLit Nothing literal shadows
in
dsExpr (HsApp eq_chk (HsVar var)) `thenDs` \ pred_expr ->
match vars shifted_eqns_for_this_lit shifted_shadows_for_this_lit `thenDs` \ inner_match_result ->
@@ -111,12 +112,42 @@ We generate:
<try-next-pattern-or-whatever>
\end{verbatim}
+
+\begin{code}
+matchLiterals all_vars@(var:vars) eqns_info@(EqnInfo ((NPlusKPat master_n k ty ge sub):ps1) _ : eqns) shadows
+ = let
+ (shifted_eqns_for_this_lit, eqns_not_for_this_lit)
+ = partitionEqnsByLit (Just master_n) k eqns_info
+ (shifted_shadows_for_this_lit, shadows_not_for_this_lit)
+ = partitionEqnsByLit (Just master_n) k shadows
+ in
+ match vars shifted_eqns_for_this_lit shifted_shadows_for_this_lit `thenDs` \ inner_match_result ->
+
+ dsExpr (HsApp ge (HsVar var)) `thenDs` \ ge_expr ->
+ dsExpr (HsApp sub (HsVar var)) `thenDs` \ nminusk_expr ->
+
+ mkGuardedMatchResult
+ ge_expr
+ (mkCoLetsMatchResult [NonRec master_n nminusk_expr] inner_match_result)
+ `thenDs` \ match_result1 ->
+
+ if (null eqns_not_for_this_lit)
+ then
+ returnDs match_result1
+ else
+ matchLiterals all_vars eqns_not_for_this_lit shadows_not_for_this_lit `thenDs` \ match_result2 ->
+ combineMatchResults match_result1 match_result2
+\end{code}
+
Given a blob of LitPats/NPats, we want to split them into those
that are ``same''/different as one we are looking at. We need to know
whether we're looking at a LitPat/NPat, and what literal we're after.
\begin{code}
-partitionEqnsByLit :: HsLit
+partitionEqnsByLit :: Maybe Id -- (Just v) for N-plus-K patterns, where v
+ -- is the "master" variable;
+ -- Nothing for NPats and LitPats
+ -> HsLit
-> [EquationInfo]
-> ([EquationInfo], -- These ones are for this lit, AND
-- they've been "shifted" by stripping
@@ -125,27 +156,34 @@ partitionEqnsByLit :: HsLit
-- are exactly as fed in.
)
-partitionEqnsByLit lit eqns
+partitionEqnsByLit nPlusK lit eqns
= ( \ (xs,ys) -> (catMaybes xs, catMaybes ys))
- (unzip (map (partition_eqn lit) eqns))
+ (unzip (map (partition_eqn nPlusK lit) eqns))
where
- partition_eqn :: HsLit -> EquationInfo ->
+ partition_eqn :: Maybe Id -> HsLit -> EquationInfo ->
(Maybe EquationInfo, Maybe EquationInfo)
- partition_eqn lit (EqnInfo (LitPat k _ : remaining_pats) match_result)
+ partition_eqn Nothing lit (EqnInfo (LitPat k _ : remaining_pats) match_result)
| lit `eq_lit` k = (Just (EqnInfo remaining_pats match_result), Nothing)
- -- NB the pattern is stripped off thhe EquationInfo
+ -- NB the pattern is stripped off the EquationInfo
- partition_eqn lit (EqnInfo (NPat k _ _ : remaining_pats) match_result)
+ partition_eqn Nothing lit (EqnInfo (NPat k _ _ : remaining_pats) match_result)
| lit `eq_lit` k = (Just (EqnInfo remaining_pats match_result), Nothing)
- -- NB the pattern is stripped off thhe EquationInfo
+ -- NB the pattern is stripped off the EquationInfo
+
+ partition_eqn (Just master_n) lit (EqnInfo (NPlusKPat n k _ _ _ : remaining_pats) match_result)
+ | lit `eq_lit` k = (Just (EqnInfo remaining_pats new_match_result), Nothing)
+ -- NB the pattern is stripped off the EquationInfo
+ where
+ new_match_result | master_n == n = match_result
+ | otherwise = mkCoLetsMatchResult [NonRec n (Var master_n)] match_result
-- Wild-card patterns, which will only show up in the shadows, go into both groups
- partition_eqn lit eqn@(EqnInfo (WildPat _ : remaining_pats) match_result)
+ partition_eqn nPlusK lit eqn@(EqnInfo (WildPat _ : remaining_pats) match_result)
= (Just (EqnInfo remaining_pats match_result), Just eqn)
-- Default case; not for this pattern
- partition_eqn lit eqn = (Nothing, Just eqn)
+ partition_eqn nPlusK lit eqn = (Nothing, Just eqn)
-- ToDo: meditate about this equality business...