2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[DsUtils]{Utilities for desugaring}
6 This module exports some utility functions of no great interest.
10 CanItFail(..), EquationInfo(..), MatchResult(..),
17 cantFailMatchResult, extractMatchResult,
19 adjustMatchResult, adjustMatchResultDs,
20 mkCoLetsMatchResult, mkGuardedMatchResult,
21 mkCoPrimCaseMatchResult, mkCoAlgCaseMatchResult,
23 mkErrorAppDs, mkNilExpr, mkConsExpr,
24 mkStringLit, mkStringLitFS, mkIntegerLit,
26 mkSelectorBinds, mkTupleExpr, mkTupleSelector,
31 #include "HsVersions.h"
33 import {-# SOURCE #-} Match ( matchSimply )
36 import TcHsSyn ( TypecheckedPat, outPatType, collectTypedPatBinders )
41 import CoreUtils ( exprType, mkIfThenElse )
42 import PrelInfo ( iRREFUT_PAT_ERROR_ID )
43 import MkId ( rebuildConArgs )
44 import Id ( idType, Id, mkWildId )
45 import Literal ( Literal(..), inIntRange, tARGET_MAX_INT )
46 import TyCon ( isNewTyCon, tyConDataCons, isRecursiveTyCon )
47 import DataCon ( DataCon, dataConStrictMarks, dataConId,
49 import Type ( mkFunTy, isUnLiftedType, Type, splitTyConApp )
50 import TcType ( tcTyConAppTyCon, isIntTy, isFloatTy, isDoubleTy )
51 import TysPrim ( intPrimTy, charPrimTy, floatPrimTy, doublePrimTy )
52 import TysWiredIn ( nilDataCon, consDataCon,
54 unitDataConId, unitTy,
56 intTy, intDataCon, smallIntegerDataCon,
59 stringTy, isPArrFakeCon )
60 import BasicTypes ( Boxity(..) )
61 import UniqSet ( mkUniqSet, minusUniqSet, isEmptyUniqSet, UniqSet )
62 import PrelNames ( unpackCStringName, unpackCStringUtf8Name,
63 plusIntegerName, timesIntegerName,
64 lengthPName, indexPName )
66 import UnicodeUtil ( stringToUtf8 )
67 import Util ( isSingleton )
72 %************************************************************************
74 \subsection{Tidying lit pats}
76 %************************************************************************
79 tidyLitPat :: HsLit -> TypecheckedPat -> TypecheckedPat
80 tidyLitPat (HsChar c) pat = ConPat charDataCon charTy [] [] [LitPat (HsCharPrim c) charPrimTy]
81 tidyLitPat lit pat = pat
83 tidyNPat :: HsLit -> Type -> TypecheckedPat -> TypecheckedPat
84 tidyNPat (HsString s) _ pat
85 | _LENGTH_ s <= 1 -- Short string literals only
86 = foldr (\c pat -> ConPat consDataCon stringTy [] [] [mk_char_lit c,pat])
87 (ConPat nilDataCon stringTy [] [] []) (_UNPK_INT_ s)
88 -- The stringTy is the type of the whole pattern, not
89 -- the type to instantiate (:) or [] with!
91 mk_char_lit c = ConPat charDataCon charTy [] [] [LitPat (HsCharPrim c) charPrimTy]
93 tidyNPat lit lit_ty default_pat
94 | isIntTy lit_ty = ConPat intDataCon lit_ty [] [] [LitPat (mk_int lit) intPrimTy]
95 | isFloatTy lit_ty = ConPat floatDataCon lit_ty [] [] [LitPat (mk_float lit) floatPrimTy]
96 | isDoubleTy lit_ty = ConPat doubleDataCon lit_ty [] [] [LitPat (mk_double lit) doublePrimTy]
97 | otherwise = default_pat
100 mk_int (HsInteger i) = HsIntPrim i
102 mk_float (HsInteger i) = HsFloatPrim (fromInteger i)
103 mk_float (HsRat f _) = HsFloatPrim f
105 mk_double (HsInteger i) = HsDoublePrim (fromInteger i)
106 mk_double (HsRat f _) = HsDoublePrim f
110 %************************************************************************
112 \subsection{Building lets}
114 %************************************************************************
116 Use case, not let for unlifted types. The simplifier will turn some
120 mkDsLet :: CoreBind -> CoreExpr -> CoreExpr
121 mkDsLet (NonRec bndr rhs) body
122 | isUnLiftedType (idType bndr) = Case rhs bndr [(DEFAULT,[],body)]
126 mkDsLets :: [CoreBind] -> CoreExpr -> CoreExpr
127 mkDsLets binds body = foldr mkDsLet body binds
131 %************************************************************************
133 \subsection{ Selecting match variables}
135 %************************************************************************
137 We're about to match against some patterns. We want to make some
138 @Ids@ to use as match variables. If a pattern has an @Id@ readily at
139 hand, which should indeed be bound to the pattern as a whole, then use it;
140 otherwise, make one up.
143 selectMatchVar :: TypecheckedPat -> DsM Id
144 selectMatchVar (VarPat var) = returnDs var
145 selectMatchVar (AsPat var pat) = returnDs var
146 selectMatchVar (LazyPat pat) = selectMatchVar pat
147 selectMatchVar other_pat = newSysLocalDs (outPatType other_pat) -- OK, better make up one...
151 %************************************************************************
153 %* type synonym EquationInfo and access functions for its pieces *
155 %************************************************************************
156 \subsection[EquationInfo-synonym]{@EquationInfo@: a useful synonym}
158 The ``equation info'' used by @match@ is relatively complicated and
159 worthy of a type synonym and a few handy functions.
164 type EqnSet = UniqSet EqnNo
168 EqnNo -- The number of the equation
170 DsMatchContext -- The context info is used when producing warnings
171 -- about shadowed patterns. It's the context
172 -- of the *first* thing matched in this group.
173 -- Should perhaps be a list of them all!
175 [TypecheckedPat] -- The patterns for an eqn
177 MatchResult -- Encapsulates the guards and bindings
183 CanItFail -- Tells whether the failure expression is used
184 (CoreExpr -> DsM CoreExpr)
185 -- Takes a expression to plug in at the
186 -- failure point(s). The expression should
189 data CanItFail = CanFail | CantFail
191 orFail CantFail CantFail = CantFail
195 Functions on MatchResults
198 cantFailMatchResult :: CoreExpr -> MatchResult
199 cantFailMatchResult expr = MatchResult CantFail (\ ignore -> returnDs expr)
201 extractMatchResult :: MatchResult -> CoreExpr -> DsM CoreExpr
202 extractMatchResult (MatchResult CantFail match_fn) fail_expr
203 = match_fn (error "It can't fail!")
205 extractMatchResult (MatchResult CanFail match_fn) fail_expr
206 = mkFailurePair fail_expr `thenDs` \ (fail_bind, if_it_fails) ->
207 match_fn if_it_fails `thenDs` \ body ->
208 returnDs (mkDsLet fail_bind body)
211 combineMatchResults :: MatchResult -> MatchResult -> MatchResult
212 combineMatchResults (MatchResult CanFail body_fn1)
213 (MatchResult can_it_fail2 body_fn2)
214 = MatchResult can_it_fail2 body_fn
216 body_fn fail = body_fn2 fail `thenDs` \ body2 ->
217 mkFailurePair body2 `thenDs` \ (fail_bind, duplicatable_expr) ->
218 body_fn1 duplicatable_expr `thenDs` \ body1 ->
219 returnDs (Let fail_bind body1)
221 combineMatchResults match_result1@(MatchResult CantFail body_fn1) match_result2
225 adjustMatchResult :: (CoreExpr -> CoreExpr) -> MatchResult -> MatchResult
226 adjustMatchResult encl_fn (MatchResult can_it_fail body_fn)
227 = MatchResult can_it_fail (\fail -> body_fn fail `thenDs` \ body ->
228 returnDs (encl_fn body))
230 adjustMatchResultDs :: (CoreExpr -> DsM CoreExpr) -> MatchResult -> MatchResult
231 adjustMatchResultDs encl_fn (MatchResult can_it_fail body_fn)
232 = MatchResult can_it_fail (\fail -> body_fn fail `thenDs` \ body ->
236 mkCoLetsMatchResult :: [CoreBind] -> MatchResult -> MatchResult
237 mkCoLetsMatchResult binds match_result
238 = adjustMatchResult (mkDsLets binds) match_result
241 mkGuardedMatchResult :: CoreExpr -> MatchResult -> MatchResult
242 mkGuardedMatchResult pred_expr (MatchResult can_it_fail body_fn)
243 = MatchResult CanFail (\fail -> body_fn fail `thenDs` \ body ->
244 returnDs (mkIfThenElse pred_expr body fail))
246 mkCoPrimCaseMatchResult :: Id -- Scrutinee
247 -> [(Literal, MatchResult)] -- Alternatives
249 mkCoPrimCaseMatchResult var match_alts
250 = MatchResult CanFail mk_case
253 = mapDs (mk_alt fail) match_alts `thenDs` \ alts ->
254 returnDs (Case (Var var) var ((DEFAULT, [], fail) : alts))
256 mk_alt fail (lit, MatchResult _ body_fn) = body_fn fail `thenDs` \ body ->
257 returnDs (LitAlt lit, [], body)
260 mkCoAlgCaseMatchResult :: Id -- Scrutinee
261 -> [(DataCon, [CoreBndr], MatchResult)] -- Alternatives
264 mkCoAlgCaseMatchResult var match_alts
265 | isNewTyCon tycon -- Newtype case; use a let
266 = ASSERT( null (tail match_alts) && null (tail arg_ids) )
267 mkCoLetsMatchResult [NonRec arg_id newtype_rhs] match_result
269 | isPArrFakeAlts match_alts -- Sugared parallel array; use a literal case
270 = MatchResult CanFail mk_parrCase
272 | otherwise -- Datatype case; use a case
273 = MatchResult fail_flag mk_case
276 scrut_ty = idType var
277 tycon = tcTyConAppTyCon scrut_ty -- Newtypes must be opaque here
280 (_, arg_ids, match_result) = head match_alts
281 arg_id = head arg_ids
283 newtype_rhs | isRecursiveTyCon tycon -- Recursive case; need a case
284 = Note (Coerce (idType arg_id) scrut_ty) (Var var)
285 | otherwise -- Normal case (newtype is transparent)
288 -- Stuff for data types
289 data_cons = tyConDataCons tycon
291 match_results = [match_result | (_,_,match_result) <- match_alts]
293 fail_flag | exhaustive_case
294 = foldr1 orFail [can_it_fail | MatchResult can_it_fail _ <- match_results]
298 wild_var = mkWildId (idType var)
299 mk_case fail = mapDs (mk_alt fail) match_alts `thenDs` \ alts ->
300 returnDs (Case (Var var) wild_var (mk_default fail ++ alts))
302 mk_alt fail (con, args, MatchResult _ body_fn)
303 = body_fn fail `thenDs` \ body ->
304 getUniquesDs `thenDs` \ us ->
306 (binds, real_args) = rebuildConArgs args (dataConStrictMarks con) us
308 returnDs (DataAlt con, real_args, mkDsLets binds body)
310 mk_default fail | exhaustive_case = []
311 | otherwise = [(DEFAULT, [], fail)]
313 un_mentioned_constructors
314 = mkUniqSet data_cons `minusUniqSet` mkUniqSet [ con | (con, _, _) <- match_alts]
315 exhaustive_case = isEmptyUniqSet un_mentioned_constructors
317 -- Stuff for parallel arrays
319 -- * the following is to desugar cases over fake constructors for
320 -- parallel arrays, which are introduced by `tidy1' in the `PArrPat'
323 -- Concerning `isPArrFakeAlts':
325 -- * it is *not* sufficient to just check the type of the type
326 -- constructor, as we have to be careful not to confuse the real
327 -- representation of parallel arrays with the fake constructors;
328 -- moreover, a list of alternatives must not mix fake and real
329 -- constructors (this is checked earlier on)
331 -- FIXME: We actually go through the whole list and make sure that
332 -- either all or none of the constructors are fake parallel
333 -- array constructors. This is to spot equations that mix fake
334 -- constructors with the real representation defined in
335 -- `PrelPArr'. It would be nicer to spot this situation
336 -- earlier and raise a proper error message, but it can really
337 -- only happen in `PrelPArr' anyway.
339 isPArrFakeAlts [(dcon, _, _)] = isPArrFakeCon dcon
340 isPArrFakeAlts ((dcon, _, _):alts) =
341 case (isPArrFakeCon dcon, isPArrFakeAlts alts) of
342 (True , True ) -> True
343 (False, False) -> False
345 panic "DsUtils: You may not mix `[:...:]' with `PArr' patterns"
348 dsLookupGlobalValue lengthPName `thenDs` \lengthP ->
349 unboxAlt `thenDs` \alt ->
350 returnDs (Case (len lengthP) (mkWildId intTy) [alt])
352 elemTy = case splitTyConApp (idType var) of
353 (_, [elemTy]) -> elemTy
355 panicMsg = "DsUtils.mkCoAlgCaseMatchResult: not a parallel array?"
356 len lengthP = mkApps (Var lengthP) [Type elemTy, Var var]
359 newSysLocalDs intPrimTy `thenDs` \l ->
360 dsLookupGlobalValue indexPName `thenDs` \indexP ->
361 mapDs (mkAlt indexP) match_alts `thenDs` \alts ->
362 returnDs (DataAlt intDataCon, [l], (Case (Var l) wild (dft : alts)))
364 wild = mkWildId intPrimTy
365 dft = (DEFAULT, [], fail)
367 -- each alternative matches one array length (corresponding to one
368 -- fake array constructor), so the match is on a literal; each
369 -- alternative's body is extended by a local binding for each
370 -- constructor argument, which are bound to array elements starting
373 mkAlt indexP (con, args, MatchResult _ bodyFun) =
374 bodyFun fail `thenDs` \body ->
375 returnDs (LitAlt lit, [], mkDsLets binds body)
377 lit = MachInt $ toInteger (dataConSourceArity con)
378 binds = [NonRec arg (indexExpr i) | (i, arg) <- zip [1..] args]
380 indexExpr i = mkApps (Var indexP) [Type elemTy, Var var, toInt i]
381 toInt i = mkConApp intDataCon [Lit $ MachInt i]
385 %************************************************************************
387 \subsection{Desugarer's versions of some Core functions}
389 %************************************************************************
392 mkErrorAppDs :: Id -- The error function
393 -> Type -- Type to which it should be applied
394 -> String -- The error message string to pass
397 mkErrorAppDs err_id ty msg
398 = getSrcLocDs `thenDs` \ src_loc ->
400 full_msg = showSDoc (hcat [ppr src_loc, text "|", text msg])
402 mkStringLit full_msg `thenDs` \ core_msg ->
403 returnDs (mkApps (Var err_id) [Type ty, core_msg])
407 *************************************************************
409 \subsection{Making literals}
411 %************************************************************************
414 mkIntegerLit :: Integer -> DsM CoreExpr
416 | inIntRange i -- Small enough, so start from an Int
417 = returnDs (mkSmallIntegerLit i)
419 -- Special case for integral literals with a large magnitude:
420 -- They are transformed into an expression involving only smaller
421 -- integral literals. This improves constant folding.
423 | otherwise -- Big, so start from a string
424 = dsLookupGlobalValue plusIntegerName `thenDs` \ plus_id ->
425 dsLookupGlobalValue timesIntegerName `thenDs` \ times_id ->
427 plus a b = Var plus_id `App` a `App` b
428 times a b = Var times_id `App` a `App` b
430 -- Transform i into (x1 + (x2 + (x3 + (...) * b) * b) * b) with abs xi <= b
431 horner :: Integer -> Integer -> CoreExpr
432 horner b i | abs q <= 1 = if r == 0 || r == i
433 then mkSmallIntegerLit i
434 else mkSmallIntegerLit r `plus` mkSmallIntegerLit (i-r)
435 | r == 0 = horner b q `times` mkSmallIntegerLit b
436 | otherwise = mkSmallIntegerLit r `plus` (horner b q `times` mkSmallIntegerLit b)
438 (q,r) = i `quotRem` b
441 returnDs (horner tARGET_MAX_INT i)
443 mkSmallIntegerLit i = mkConApp smallIntegerDataCon [mkIntLit i]
445 mkStringLit :: String -> DsM CoreExpr
446 mkStringLit str = mkStringLitFS (_PK_ str)
448 mkStringLitFS :: FAST_STRING -> DsM CoreExpr
451 = returnDs (mkNilExpr charTy)
455 the_char = mkConApp charDataCon [mkLit (MachChar (_HEAD_INT_ str))]
457 returnDs (mkConsExpr charTy the_char (mkNilExpr charTy))
460 = dsLookupGlobalValue unpackCStringName `thenDs` \ unpack_id ->
461 returnDs (App (Var unpack_id) (Lit (MachStr str)))
464 = dsLookupGlobalValue unpackCStringUtf8Name `thenDs` \ unpack_id ->
465 returnDs (App (Var unpack_id) (Lit (MachStr (_PK_ (stringToUtf8 chars)))))
468 chars = _UNPK_INT_ str
469 safeChar c = c >= 1 && c <= 0xFF
473 %************************************************************************
475 \subsection[mkSelectorBind]{Make a selector bind}
477 %************************************************************************
479 This is used in various places to do with lazy patterns.
480 For each binder $b$ in the pattern, we create a binding:
482 b = case v of pat' -> b'
484 where @pat'@ is @pat@ with each binder @b@ cloned into @b'@.
486 ToDo: making these bindings should really depend on whether there's
487 much work to be done per binding. If the pattern is complex, it
488 should be de-mangled once, into a tuple (and then selected from).
489 Otherwise the demangling can be in-line in the bindings (as here).
491 Boring! Boring! One error message per binder. The above ToDo is
492 even more helpful. Something very similar happens for pattern-bound
496 mkSelectorBinds :: TypecheckedPat -- The pattern
497 -> CoreExpr -- Expression to which the pattern is bound
498 -> DsM [(Id,CoreExpr)]
500 mkSelectorBinds (VarPat v) val_expr
501 = returnDs [(v, val_expr)]
503 mkSelectorBinds pat val_expr
504 | isSingleton binders || is_simple_pat pat
505 = newSysLocalDs (exprType val_expr) `thenDs` \ val_var ->
507 -- For the error message we don't use mkErrorAppDs to avoid
508 -- duplicating the string literal each time
509 newSysLocalDs stringTy `thenDs` \ msg_var ->
510 getSrcLocDs `thenDs` \ src_loc ->
512 full_msg = showSDoc (hcat [ppr src_loc, text "|", ppr pat])
514 mkStringLit full_msg `thenDs` \ core_msg ->
515 mapDs (mk_bind val_var msg_var) binders `thenDs` \ binds ->
516 returnDs ( (val_var, val_expr) :
517 (msg_var, core_msg) :
522 = mkErrorAppDs iRREFUT_PAT_ERROR_ID
523 tuple_ty (showSDoc (ppr pat)) `thenDs` \ error_expr ->
524 matchSimply val_expr PatBindRhs pat local_tuple error_expr `thenDs` \ tuple_expr ->
525 newSysLocalDs tuple_ty `thenDs` \ tuple_var ->
528 = (binder, mkTupleSelector binders binder tuple_var (Var tuple_var))
530 returnDs ( (tuple_var, tuple_expr) : map mk_tup_bind binders )
532 binders = collectTypedPatBinders pat
533 local_tuple = mkTupleExpr binders
534 tuple_ty = exprType local_tuple
536 mk_bind scrut_var msg_var bndr_var
537 -- (mk_bind sv bv) generates
538 -- bv = case sv of { pat -> bv; other -> error-msg }
539 -- Remember, pat binds bv
540 = matchSimply (Var scrut_var) PatBindRhs pat
541 (Var bndr_var) error_expr `thenDs` \ rhs_expr ->
542 returnDs (bndr_var, rhs_expr)
544 binder_ty = idType bndr_var
545 error_expr = mkApps (Var iRREFUT_PAT_ERROR_ID) [Type binder_ty, Var msg_var]
547 is_simple_pat (TuplePat ps Boxed) = all is_triv_pat ps
548 is_simple_pat (ConPat _ _ _ _ ps) = all is_triv_pat ps
549 is_simple_pat (VarPat _) = True
550 is_simple_pat (RecPat _ _ _ _ ps) = and [is_triv_pat p | (_,p,_) <- ps]
551 is_simple_pat other = False
553 is_triv_pat (VarPat v) = True
554 is_triv_pat (WildPat _) = True
555 is_triv_pat other = False
559 @mkTupleExpr@ builds a tuple; the inverse to @mkTupleSelector@. If it
560 has only one element, it is the identity function.
563 mkTupleExpr :: [Id] -> CoreExpr
565 mkTupleExpr [] = Var unitDataConId
566 mkTupleExpr [id] = Var id
567 mkTupleExpr ids = mkConApp (tupleCon Boxed (length ids))
568 (map (Type . idType) ids ++ [ Var i | i <- ids ])
572 @mkTupleSelector@ builds a selector which scrutises the given
573 expression and extracts the one name from the list given.
574 If you want the no-shadowing rule to apply, the caller
575 is responsible for making sure that none of these names
578 If there is just one id in the ``tuple'', then the selector is
582 mkTupleSelector :: [Id] -- The tuple args
583 -> Id -- The selected one
584 -> Id -- A variable of the same type as the scrutinee
585 -> CoreExpr -- Scrutinee
588 mkTupleSelector [var] should_be_the_same_var scrut_var scrut
589 = ASSERT(var == should_be_the_same_var)
592 mkTupleSelector vars the_var scrut_var scrut
593 = ASSERT( not (null vars) )
594 Case scrut scrut_var [(DataAlt (tupleCon Boxed (length vars)), vars, Var the_var)]
598 %************************************************************************
600 \subsection[mkFailurePair]{Code for pattern-matching and other failures}
602 %************************************************************************
604 Call the constructor Ids when building explicit lists, so that they
605 interact well with rules.
608 mkNilExpr :: Type -> CoreExpr
609 mkNilExpr ty = App (Var (dataConId nilDataCon)) (Type ty)
611 mkConsExpr :: Type -> CoreExpr -> CoreExpr -> CoreExpr
612 mkConsExpr ty hd tl = mkApps (Var (dataConId consDataCon)) [Type ty, hd, tl]
616 %************************************************************************
618 \subsection[mkFailurePair]{Code for pattern-matching and other failures}
620 %************************************************************************
622 Generally, we handle pattern matching failure like this: let-bind a
623 fail-variable, and use that variable if the thing fails:
625 let fail.33 = error "Help"
636 If the case can't fail, then there'll be no mention of @fail.33@, and the
637 simplifier will later discard it.
640 If it can fail in only one way, then the simplifier will inline it.
643 Only if it is used more than once will the let-binding remain.
646 There's a problem when the result of the case expression is of
647 unboxed type. Then the type of @fail.33@ is unboxed too, and
648 there is every chance that someone will change the let into a case:
654 which is of course utterly wrong. Rather than drop the condition that
655 only boxed types can be let-bound, we just turn the fail into a function
656 for the primitive case:
658 let fail.33 :: Void -> Int#
659 fail.33 = \_ -> error "Help"
668 Now @fail.33@ is a function, so it can be let-bound.
671 mkFailurePair :: CoreExpr -- Result type of the whole case expression
672 -> DsM (CoreBind, -- Binds the newly-created fail variable
673 -- to either the expression or \ _ -> expression
674 CoreExpr) -- Either the fail variable, or fail variable
675 -- applied to unit tuple
678 = newFailLocalDs (unitTy `mkFunTy` ty) `thenDs` \ fail_fun_var ->
679 newSysLocalDs unitTy `thenDs` \ fail_fun_arg ->
680 returnDs (NonRec fail_fun_var (Lam fail_fun_arg expr),
681 App (Var fail_fun_var) (Var unitDataConId))
684 = newFailLocalDs ty `thenDs` \ fail_var ->
685 returnDs (NonRec fail_var expr, Var fail_var)