[project @ 1998-04-30 19:31:03 by sof]
[ghc-hetmet.git] / ghc / compiler / deSugar / DsUtils.lhs
index ec7d252..2685e65 100644 (file)
@@ -6,15 +6,13 @@
 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,
@@ -22,55 +20,40 @@ module DsUtils (
        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}
 
 
@@ -213,15 +196,12 @@ mkCoAlgCaseMatchResult var alts
   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
@@ -281,7 +261,6 @@ dsArgToAtom :: DsCoreArg                -- The argument expression
                                            -- 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
@@ -299,7 +278,7 @@ dsExprToAtomGivenTy arg_expr arg_ty 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
     )
@@ -323,7 +302,7 @@ dsArgsToAtoms (arg:args) continue_with
 %************************************************************************
 
 \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
@@ -344,7 +323,7 @@ mkPrimDs op args
 
 \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
@@ -354,10 +333,10 @@ mkErrorAppDs :: Id                -- The error function
 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}
 
 %************************************************************************
@@ -391,57 +370,69 @@ mkSelectorBinds (VarPat v) val_expr
   = 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}
@@ -462,17 +453,13 @@ mkTupleSelector :: [Id]                   -- The tuple args
                -> 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}
 
 
@@ -538,7 +525,7 @@ mkFailurePair :: Type               -- Result type of the whole case expression
                      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 ->