2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1997-1998
5 \section[BasicTypes]{Miscellanous types}
7 This module defines a miscellaneously collection of very simple
11 \item have no other obvious home
12 \item don't depend on any other complicated types
13 \item are used in more than one "part" of the compiler
18 Version, bumpVersion, initialVersion,
26 Fixity(..), FixityDirection(..),
27 defaultFixity, maxPrecedence,
28 negateFixity, funTyFixity,
31 IPName(..), ipNameName, mapIPName,
33 RecFlag(..), isRec, isNonRec, boolToRecFlag,
37 TopLevelFlag(..), isTopLevel, isNotTopLevel,
43 TupCon(..), tupleParens,
45 OccInfo(..), seqOccInfo, zapFragileOcc, isOneOcc,
46 isDeadOcc, isLoopBreaker, isNonRuleLoopBreaker, isNoOcc,
49 InsideLam, insideLam, notInsideLam,
50 OneBranch, oneBranch, notOneBranch,
55 StrictnessMark(..), isMarkedUnboxed, isMarkedStrict,
58 Activation(..), isActive, isNeverActive, isAlwaysActive, isEarlyActive,
59 RuleMatchInfo(..), isConLike, isFunLike,
60 InlinePragma(..), defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma,
61 isDefaultInlinePragma, isInlinePragma, inlinePragmaSat,
62 inlinePragmaActivation, inlinePragmaRuleMatchInfo,
63 setInlinePragmaActivation, setInlinePragmaRuleMatchInfo,
65 SuccessFlag(..), succeeded, failed, successIf
72 %************************************************************************
74 \subsection[Arity]{Arity}
76 %************************************************************************
82 %************************************************************************
84 \subsection[FunctionOrData]{FunctionOrData}
86 %************************************************************************
89 data FunctionOrData = IsFunction | IsData
92 instance Outputable FunctionOrData where
93 ppr IsFunction = text "(function)"
94 ppr IsData = text "(data)"
98 %************************************************************************
100 \subsection[Version]{Module and identifier version numbers}
102 %************************************************************************
107 bumpVersion :: Version -> Version
110 initialVersion :: Version
114 %************************************************************************
118 %************************************************************************
122 -- reason/explanation from a WARNING or DEPRECATED pragma
123 data WarningTxt = WarningTxt [FastString]
124 | DeprecatedTxt [FastString]
127 instance Outputable WarningTxt where
128 ppr (WarningTxt ws) = doubleQuotes (vcat (map ftext ws))
129 ppr (DeprecatedTxt ds) = text "Deprecated:" <+>
130 doubleQuotes (vcat (map ftext ds))
133 %************************************************************************
135 \subsection{Implicit parameter identity}
137 %************************************************************************
139 The @IPName@ type is here because it is used in TypeRep (i.e. very
140 early in the hierarchy), but also in HsSyn.
143 newtype IPName name = IPName name -- ?x
144 deriving( Eq, Ord ) -- Ord is used in the IP name cache finite map
145 -- (used in HscTypes.OrigIParamCache)
147 ipNameName :: IPName name -> name
148 ipNameName (IPName n) = n
150 mapIPName :: (a->b) -> IPName a -> IPName b
151 mapIPName f (IPName n) = IPName (f n)
153 instance Outputable name => Outputable (IPName name) where
154 ppr (IPName n) = char '?' <> ppr n -- Ordinary implicit parameters
157 %************************************************************************
161 %************************************************************************
164 type RuleName = FastString
167 %************************************************************************
169 \subsection[Fixity]{Fixity info}
171 %************************************************************************
174 ------------------------
175 data Fixity = Fixity Int FixityDirection
177 instance Outputable Fixity where
178 ppr (Fixity prec dir) = hcat [ppr dir, space, int prec]
180 instance Eq Fixity where -- Used to determine if two fixities conflict
181 (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
183 ------------------------
184 data FixityDirection = InfixL | InfixR | InfixN
187 instance Outputable FixityDirection where
188 ppr InfixL = ptext (sLit "infixl")
189 ppr InfixR = ptext (sLit "infixr")
190 ppr InfixN = ptext (sLit "infix")
192 ------------------------
195 defaultFixity :: Fixity
196 defaultFixity = Fixity maxPrecedence InfixL
198 negateFixity, funTyFixity :: Fixity
200 negateFixity = Fixity 6 InfixL -- Fixity of unary negate
201 funTyFixity = Fixity 0 InfixR -- Fixity of '->'
209 @(compareFixity op1 op2)@ tells which way to arrange appication, or
210 whether there's an error.
213 compareFixity :: Fixity -> Fixity
214 -> (Bool, -- Error please
215 Bool) -- Associate to the right: a op1 (b op2 c)
216 compareFixity (Fixity prec1 dir1) (Fixity prec2 dir2)
217 = case prec1 `compare` prec2 of
220 EQ -> case (dir1, dir2) of
221 (InfixR, InfixR) -> right
222 (InfixL, InfixL) -> left
225 right = (False, True)
226 left = (False, False)
227 error_please = (True, False)
231 %************************************************************************
233 \subsection[Top-level/local]{Top-level/not-top level flag}
235 %************************************************************************
242 isTopLevel, isNotTopLevel :: TopLevelFlag -> Bool
244 isNotTopLevel NotTopLevel = True
245 isNotTopLevel TopLevel = False
247 isTopLevel TopLevel = True
248 isTopLevel NotTopLevel = False
250 instance Outputable TopLevelFlag where
251 ppr TopLevel = ptext (sLit "<TopLevel>")
252 ppr NotTopLevel = ptext (sLit "<NotTopLevel>")
256 %************************************************************************
258 Top-level/not-top level flag
260 %************************************************************************
268 isBoxed :: Boxity -> Bool
270 isBoxed Unboxed = False
274 %************************************************************************
276 Recursive/Non-Recursive flag
278 %************************************************************************
281 data RecFlag = Recursive
285 isRec :: RecFlag -> Bool
286 isRec Recursive = True
287 isRec NonRecursive = False
289 isNonRec :: RecFlag -> Bool
290 isNonRec Recursive = False
291 isNonRec NonRecursive = True
293 boolToRecFlag :: Bool -> RecFlag
294 boolToRecFlag True = Recursive
295 boolToRecFlag False = NonRecursive
297 instance Outputable RecFlag where
298 ppr Recursive = ptext (sLit "Recursive")
299 ppr NonRecursive = ptext (sLit "NonRecursive")
302 %************************************************************************
304 Instance overlap flag
306 %************************************************************************
310 = NoOverlap -- This instance must not overlap another
312 | OverlapOk -- Silently ignore this instance if you find a
313 -- more specific one that matches the constraint
314 -- you are trying to resolve
316 -- Example: constraint (Foo [Int])
317 -- instances (Foo [Int])
318 -- (Foo [a]) OverlapOk
319 -- Since the second instance has the OverlapOk flag,
320 -- the first instance will be chosen (otherwise
321 -- its ambiguous which to choose)
323 | Incoherent -- Like OverlapOk, but also ignore this instance
324 -- if it doesn't match the constraint you are
325 -- trying to resolve, but could match if the type variables
326 -- in the constraint were instantiated
328 -- Example: constraint (Foo [b])
329 -- instances (Foo [Int]) Incoherent
331 -- Without the Incoherent flag, we'd complain that
332 -- instantiating 'b' would change which instance
336 instance Outputable OverlapFlag where
337 ppr NoOverlap = empty
338 ppr OverlapOk = ptext (sLit "[overlap ok]")
339 ppr Incoherent = ptext (sLit "[incoherent]")
343 %************************************************************************
347 %************************************************************************
350 data TupCon = TupCon Boxity Arity
352 instance Eq TupCon where
353 (TupCon b1 a1) == (TupCon b2 a2) = b1==b2 && a1==a2
355 tupleParens :: Boxity -> SDoc -> SDoc
356 tupleParens Boxed p = parens p
357 tupleParens Unboxed p = ptext (sLit "(#") <+> p <+> ptext (sLit "#)")
360 %************************************************************************
362 \subsection[Generic]{Generic flag}
364 %************************************************************************
366 This is the "Embedding-Projection pair" datatype, it contains
367 two pieces of code (normally either RenamedExpr's or Id's)
368 If we have a such a pair (EP from to), the idea is that 'from' and 'to'
369 represents functions of type
378 T and Tring are arbitrary, but typically T is the 'main' type while
379 Tring is the 'representation' type. (This just helps us remember
380 whether to use 'from' or 'to'.
383 data EP a = EP { fromEP :: a, -- :: T -> Tring
384 toEP :: a } -- :: Tring -> T
387 Embedding-projection pairs are used in several places:
389 First of all, each type constructor has an EP associated with it, the
390 code in EP converts (datatype T) from T to Tring and back again.
392 Secondly, when we are filling in Generic methods (in the typechecker,
393 tcMethodBinds), we are constructing bimaps by induction on the structure
394 of the type of the method signature.
397 %************************************************************************
399 \subsection{Occurrence information}
401 %************************************************************************
403 This data type is used exclusively by the simplifier, but it appears in a
404 SubstResult, which is currently defined in VarEnv, which is pretty near
405 the base of the module hierarchy. So it seemed simpler to put the
406 defn of OccInfo here, safely at the bottom
409 -- | Identifier occurrence information
411 = NoOccInfo -- ^ There are many occurrences, or unknown occurences
413 | IAmDead -- ^ Marks unused variables. Sometimes useful for
414 -- lambda and case-bound variables.
419 !InterestingCxt -- ^ Occurs exactly once, not inside a rule
421 -- | This identifier breaks a loop of mutually recursive functions. The field
422 -- marks whether it is only a loop breaker due to a reference in a rule
423 | IAmALoopBreaker -- Note [LoopBreaker OccInfo]
424 !RulesOnly -- True <=> This is a weak or rules-only loop breaker
425 -- See OccurAnal Note [Weak loop breakers]
427 type RulesOnly = Bool
430 Note [LoopBreaker OccInfo]
431 ~~~~~~~~~~~~~~~~~~~~~~~~~~
432 An OccInfo of (IAmLoopBreaker False) is used by the occurrence
433 analyser in two ways:
434 (a) to mark loop-breakers in a group of recursive
435 definitions (hence the name)
436 (b) to mark binders that must not be inlined in this phase
437 (perhaps it has a NOINLINE pragma)
438 Things with (IAmLoopBreaker False) do not get an unfolding
439 pinned on to them, so they are completely opaque.
441 See OccurAnal Note [Weak loop breakers] for (IAmLoopBreaker True).
445 isNoOcc :: OccInfo -> Bool
446 isNoOcc NoOccInfo = True
449 seqOccInfo :: OccInfo -> ()
450 seqOccInfo occ = occ `seq` ()
453 type InterestingCxt = Bool -- True <=> Function: is applied
454 -- Data value: scrutinised by a case with
455 -- at least one non-DEFAULT branch
458 type InsideLam = Bool -- True <=> Occurs inside a non-linear lambda
459 -- Substituting a redex for this occurrence is
460 -- dangerous because it might duplicate work.
461 insideLam, notInsideLam :: InsideLam
466 type OneBranch = Bool -- True <=> Occurs in only one case branch
467 -- so no code-duplication issue to worry about
468 oneBranch, notOneBranch :: OneBranch
472 isLoopBreaker :: OccInfo -> Bool
473 isLoopBreaker (IAmALoopBreaker _) = True
474 isLoopBreaker _ = False
476 isNonRuleLoopBreaker :: OccInfo -> Bool
477 isNonRuleLoopBreaker (IAmALoopBreaker False) = True -- Loop-breaker that breaks a non-rule cycle
478 isNonRuleLoopBreaker _ = False
480 nonRuleLoopBreaker :: OccInfo
481 nonRuleLoopBreaker = IAmALoopBreaker False
483 isDeadOcc :: OccInfo -> Bool
484 isDeadOcc IAmDead = True
487 isOneOcc :: OccInfo -> Bool
488 isOneOcc (OneOcc {}) = True
491 zapFragileOcc :: OccInfo -> OccInfo
492 zapFragileOcc (OneOcc {}) = NoOccInfo
493 zapFragileOcc occ = occ
497 instance Outputable OccInfo where
498 -- only used for debugging; never parsed. KSW 1999-07
499 ppr NoOccInfo = empty
500 ppr (IAmALoopBreaker ro) = ptext (sLit "LoopBreaker") <> if ro then char '!' else empty
501 ppr IAmDead = ptext (sLit "Dead")
502 ppr (OneOcc inside_lam one_branch int_cxt)
503 = ptext (sLit "Once") <> pp_lam <> pp_br <> pp_args
505 pp_lam | inside_lam = char 'L'
507 pp_br | one_branch = empty
508 | otherwise = char '*'
509 pp_args | int_cxt = char '!'
512 instance Show OccInfo where
513 showsPrec p occ = showsPrecSDoc p (ppr occ)
516 %************************************************************************
518 \subsection{Strictness indication}
520 %************************************************************************
522 The strictness annotations on types in data type declarations
523 e.g. data T = MkT !Int !(Bool,Bool)
526 data StrictnessMark -- Used in interface decls only
532 isMarkedUnboxed :: StrictnessMark -> Bool
533 isMarkedUnboxed MarkedUnboxed = True
534 isMarkedUnboxed _ = False
536 isMarkedStrict :: StrictnessMark -> Bool
537 isMarkedStrict NotMarkedStrict = False
538 isMarkedStrict _ = True -- All others are strict
540 instance Outputable StrictnessMark where
541 ppr MarkedStrict = ptext (sLit "!")
542 ppr MarkedUnboxed = ptext (sLit "!!")
543 ppr NotMarkedStrict = ptext (sLit "_")
547 %************************************************************************
549 \subsection{Success flag}
551 %************************************************************************
554 data SuccessFlag = Succeeded | Failed
556 instance Outputable SuccessFlag where
557 ppr Succeeded = ptext (sLit "Succeeded")
558 ppr Failed = ptext (sLit "Failed")
560 successIf :: Bool -> SuccessFlag
561 successIf True = Succeeded
562 successIf False = Failed
564 succeeded, failed :: SuccessFlag -> Bool
565 succeeded Succeeded = True
566 succeeded Failed = False
568 failed Succeeded = False
573 %************************************************************************
575 \subsection{Activation}
577 %************************************************************************
579 When a rule or inlining is active
582 type CompilerPhase = Int -- Compilation phase
583 -- Phases decrease towards zero
584 -- Zero is the last phase
586 data Activation = NeverActive
588 | ActiveBefore CompilerPhase -- Active only *before* this phase
589 | ActiveAfter CompilerPhase -- Active in this phase and later
590 deriving( Eq ) -- Eq used in comparing rules in HsDecls
592 data RuleMatchInfo = ConLike -- See Note [CONLIKE pragma]
596 data InlinePragma -- Note [InlinePragma]
598 { inl_inline :: Bool -- True <=> INLINE,
599 -- False <=> no pragma at all, or NOINLINE
600 , inl_sat :: Maybe Arity -- Just n <=> Inline only when applied to n
601 -- explicit (non-type, non-dictionary) args
602 , inl_act :: Activation -- Says during which phases inlining is allowed
603 , inl_rule :: RuleMatchInfo -- Should the function be treated like a constructor?
609 This data type mirrors what you can write in an INLINE or NOINLINE pragma in
612 If you write nothing at all, you get defaultInlinePragma:
614 inl_act = AlwaysActive
617 It's not possible to get that combination by *writing* something, so
618 if an Id has defaultInlinePragma it means the user didn't specify anything.
620 If inl_inline = True, then the Id should have an InlineRule unfolding.
622 Note [CONLIKE pragma]
623 ~~~~~~~~~~~~~~~~~~~~~
624 The ConLike constructor of a RuleMatchInfo is aimed at the following.
626 {-# RULE "r/cons" forall a as. r (a:as) = f (a+1) #-}
627 g b bs = let x = b:bs in ..x...x...(r x)...
628 Now, the rule applies to the (r x) term, because GHC "looks through"
629 the definition of 'x' to see that it is (b:bs).
632 {-# RULE "r/f" forall v. r (f v) = f (v+1) #-}
633 g v = let x = f v in ..x...x...(r x)...
634 Normally the (r x) would *not* match the rule, because GHC would be
635 scared about duplicating the redex (f v), so it does not "look
636 through" the bindings.
638 However the CONLIKE modifier says to treat 'f' like a constructor in
639 this situation, and "look through" the unfolding for x. So (r x)
640 fires, yielding (f (v+1)).
642 This is all controlled with a user-visible pragma:
643 {-# NOINLINE CONLIKE [1] f #-}
645 The main effects of CONLIKE are:
647 - The occurrence analyser (OccAnal) and simplifier (Simplify) treat
648 CONLIKE thing like constructors, by ANF-ing them
650 - New function coreUtils.exprIsExpandable is like exprIsCheap, but
651 additionally spots applications of CONLIKE functions
653 - A CoreUnfolding has a field that caches exprIsExpandable
655 - The rule matcher consults this field. See
656 Note [Expanding variables] in Rules.lhs.
659 isConLike :: RuleMatchInfo -> Bool
660 isConLike ConLike = True
663 isFunLike :: RuleMatchInfo -> Bool
664 isFunLike FunLike = True
667 defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
669 defaultInlinePragma = InlinePragma { inl_act = AlwaysActive
672 , inl_sat = Nothing }
674 alwaysInlinePragma = defaultInlinePragma { inl_inline = True }
675 neverInlinePragma = defaultInlinePragma { inl_act = NeverActive }
676 dfunInlinePragma = defaultInlinePragma { inl_rule = ConLike }
679 isDefaultInlinePragma :: InlinePragma -> Bool
680 isDefaultInlinePragma (InlinePragma { inl_act = activation
681 , inl_rule = match_info
682 , inl_inline = inline })
683 = not inline && isAlwaysActive activation && isFunLike match_info
685 isInlinePragma :: InlinePragma -> Bool
686 isInlinePragma prag = inl_inline prag
688 inlinePragmaSat :: InlinePragma -> Maybe Arity
689 inlinePragmaSat = inl_sat
691 inlinePragmaActivation :: InlinePragma -> Activation
692 inlinePragmaActivation (InlinePragma { inl_act = activation }) = activation
694 inlinePragmaRuleMatchInfo :: InlinePragma -> RuleMatchInfo
695 inlinePragmaRuleMatchInfo (InlinePragma { inl_rule = info }) = info
697 setInlinePragmaActivation :: InlinePragma -> Activation -> InlinePragma
698 setInlinePragmaActivation prag activation = prag { inl_act = activation }
700 setInlinePragmaRuleMatchInfo :: InlinePragma -> RuleMatchInfo -> InlinePragma
701 setInlinePragmaRuleMatchInfo prag info = prag { inl_rule = info }
703 instance Outputable Activation where
704 ppr AlwaysActive = ptext (sLit "ALWAYS")
705 ppr NeverActive = ptext (sLit "NEVER")
706 ppr (ActiveBefore n) = brackets (char '~' <> int n)
707 ppr (ActiveAfter n) = brackets (int n)
709 instance Outputable RuleMatchInfo where
710 ppr ConLike = ptext (sLit "CONLIKE")
711 ppr FunLike = ptext (sLit "FUNLIKE")
713 instance Outputable InlinePragma where
714 ppr (InlinePragma { inl_inline = inline, inl_act = activation
715 , inl_rule = info, inl_sat = mb_arity })
716 = pp_inline <> pp_sat <+> pp_info <+> pp_activation
718 pp_inline | inline = ptext (sLit "INLINE")
719 | otherwise = ptext (sLit "NOINLINE")
720 pp_sat | Just ar <- mb_arity = braces (int ar)
722 pp_info | isFunLike info = empty
723 | otherwise = ppr info
725 | inline && isAlwaysActive activation = empty
726 | not inline && isNeverActive activation = empty
727 | otherwise = ppr activation
729 isActive :: CompilerPhase -> Activation -> Bool
730 isActive _ NeverActive = False
731 isActive _ AlwaysActive = True
732 isActive p (ActiveAfter n) = p <= n
733 isActive p (ActiveBefore n) = p > n
735 isNeverActive, isAlwaysActive, isEarlyActive :: Activation -> Bool
736 isNeverActive NeverActive = True
737 isNeverActive _ = False
739 isAlwaysActive AlwaysActive = True
740 isAlwaysActive _ = False
742 isEarlyActive AlwaysActive = True
743 isEarlyActive (ActiveBefore {}) = True
744 isEarlyActive _ = False