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, isFragileOcc, isOneOcc,
46 isDeadOcc, isLoopBreaker, isNonRuleLoopBreaker, isNoOcc,
48 InsideLam, insideLam, notInsideLam,
49 OneBranch, oneBranch, notOneBranch,
54 StrictnessMark(..), isMarkedUnboxed, isMarkedStrict,
57 Activation(..), isActive, isNeverActive, isAlwaysActive,
58 RuleMatchInfo(..), isConLike, isFunLike,
59 InlinePragma(..), defaultInlinePragma, isDefaultInlinePragma,
60 inlinePragmaActivation, inlinePragmaRuleMatchInfo,
61 setInlinePragmaActivation, setInlinePragmaRuleMatchInfo,
62 InlineSpec(..), defaultInlineSpec, alwaysInlineSpec, neverInlineSpec,
64 SuccessFlag(..), succeeded, failed, successIf
71 %************************************************************************
73 \subsection[Arity]{Arity}
75 %************************************************************************
81 %************************************************************************
83 \subsection[FunctionOrData]{FunctionOrData}
85 %************************************************************************
88 data FunctionOrData = IsFunction | IsData
91 instance Outputable FunctionOrData where
92 ppr IsFunction = text "(function)"
93 ppr IsData = text "(data)"
97 %************************************************************************
99 \subsection[Version]{Module and identifier version numbers}
101 %************************************************************************
106 bumpVersion :: Version -> Version
109 initialVersion :: Version
113 %************************************************************************
117 %************************************************************************
121 -- reason/explanation from a WARNING or DEPRECATED pragma
122 data WarningTxt = WarningTxt [FastString]
123 | DeprecatedTxt [FastString]
126 instance Outputable WarningTxt where
127 ppr (WarningTxt ws) = doubleQuotes (vcat (map ftext ws))
128 ppr (DeprecatedTxt ds) = text "Deprecated:" <+>
129 doubleQuotes (vcat (map ftext ds))
132 %************************************************************************
134 \subsection{Implicit parameter identity}
136 %************************************************************************
138 The @IPName@ type is here because it is used in TypeRep (i.e. very
139 early in the hierarchy), but also in HsSyn.
142 newtype IPName name = IPName name -- ?x
143 deriving( Eq, Ord ) -- Ord is used in the IP name cache finite map
144 -- (used in HscTypes.OrigIParamCache)
146 ipNameName :: IPName name -> name
147 ipNameName (IPName n) = n
149 mapIPName :: (a->b) -> IPName a -> IPName b
150 mapIPName f (IPName n) = IPName (f n)
152 instance Outputable name => Outputable (IPName name) where
153 ppr (IPName n) = char '?' <> ppr n -- Ordinary implicit parameters
156 %************************************************************************
160 %************************************************************************
163 type RuleName = FastString
166 %************************************************************************
168 \subsection[Fixity]{Fixity info}
170 %************************************************************************
173 ------------------------
174 data Fixity = Fixity Int FixityDirection
176 instance Outputable Fixity where
177 ppr (Fixity prec dir) = hcat [ppr dir, space, int prec]
179 instance Eq Fixity where -- Used to determine if two fixities conflict
180 (Fixity p1 dir1) == (Fixity p2 dir2) = p1==p2 && dir1 == dir2
182 ------------------------
183 data FixityDirection = InfixL | InfixR | InfixN
186 instance Outputable FixityDirection where
187 ppr InfixL = ptext (sLit "infixl")
188 ppr InfixR = ptext (sLit "infixr")
189 ppr InfixN = ptext (sLit "infix")
191 ------------------------
194 defaultFixity :: Fixity
195 defaultFixity = Fixity maxPrecedence InfixL
197 negateFixity, funTyFixity :: Fixity
199 negateFixity = Fixity 6 InfixL -- Fixity of unary negate
200 funTyFixity = Fixity 0 InfixR -- Fixity of '->'
208 @(compareFixity op1 op2)@ tells which way to arrange appication, or
209 whether there's an error.
212 compareFixity :: Fixity -> Fixity
213 -> (Bool, -- Error please
214 Bool) -- Associate to the right: a op1 (b op2 c)
215 compareFixity (Fixity prec1 dir1) (Fixity prec2 dir2)
216 = case prec1 `compare` prec2 of
219 EQ -> case (dir1, dir2) of
220 (InfixR, InfixR) -> right
221 (InfixL, InfixL) -> left
224 right = (False, True)
225 left = (False, False)
226 error_please = (True, False)
230 %************************************************************************
232 \subsection[Top-level/local]{Top-level/not-top level flag}
234 %************************************************************************
241 isTopLevel, isNotTopLevel :: TopLevelFlag -> Bool
243 isNotTopLevel NotTopLevel = True
244 isNotTopLevel TopLevel = False
246 isTopLevel TopLevel = True
247 isTopLevel NotTopLevel = False
249 instance Outputable TopLevelFlag where
250 ppr TopLevel = ptext (sLit "<TopLevel>")
251 ppr NotTopLevel = ptext (sLit "<NotTopLevel>")
255 %************************************************************************
257 Top-level/not-top level flag
259 %************************************************************************
267 isBoxed :: Boxity -> Bool
269 isBoxed Unboxed = False
273 %************************************************************************
275 Recursive/Non-Recursive flag
277 %************************************************************************
280 data RecFlag = Recursive
284 isRec :: RecFlag -> Bool
285 isRec Recursive = True
286 isRec NonRecursive = False
288 isNonRec :: RecFlag -> Bool
289 isNonRec Recursive = False
290 isNonRec NonRecursive = True
292 boolToRecFlag :: Bool -> RecFlag
293 boolToRecFlag True = Recursive
294 boolToRecFlag False = NonRecursive
296 instance Outputable RecFlag where
297 ppr Recursive = ptext (sLit "Recursive")
298 ppr NonRecursive = ptext (sLit "NonRecursive")
301 %************************************************************************
303 Instance overlap flag
305 %************************************************************************
309 = NoOverlap -- This instance must not overlap another
311 | OverlapOk -- Silently ignore this instance if you find a
312 -- more specific one that matches the constraint
313 -- you are trying to resolve
315 -- Example: constraint (Foo [Int])
316 -- instances (Foo [Int])
317 -- (Foo [a]) OverlapOk
318 -- Since the second instance has the OverlapOk flag,
319 -- the first instance will be chosen (otherwise
320 -- its ambiguous which to choose)
322 | Incoherent -- Like OverlapOk, but also ignore this instance
323 -- if it doesn't match the constraint you are
324 -- trying to resolve, but could match if the type variables
325 -- in the constraint were instantiated
327 -- Example: constraint (Foo [b])
328 -- instances (Foo [Int]) Incoherent
330 -- Without the Incoherent flag, we'd complain that
331 -- instantiating 'b' would change which instance
335 instance Outputable OverlapFlag where
336 ppr NoOverlap = empty
337 ppr OverlapOk = ptext (sLit "[overlap ok]")
338 ppr Incoherent = ptext (sLit "[incoherent]")
342 %************************************************************************
346 %************************************************************************
349 data TupCon = TupCon Boxity Arity
351 instance Eq TupCon where
352 (TupCon b1 a1) == (TupCon b2 a2) = b1==b2 && a1==a2
354 tupleParens :: Boxity -> SDoc -> SDoc
355 tupleParens Boxed p = parens p
356 tupleParens Unboxed p = ptext (sLit "(#") <+> p <+> ptext (sLit "#)")
359 %************************************************************************
361 \subsection[Generic]{Generic flag}
363 %************************************************************************
365 This is the "Embedding-Projection pair" datatype, it contains
366 two pieces of code (normally either RenamedExpr's or Id's)
367 If we have a such a pair (EP from to), the idea is that 'from' and 'to'
368 represents functions of type
377 T and Tring are arbitrary, but typically T is the 'main' type while
378 Tring is the 'representation' type. (This just helps us remember
379 whether to use 'from' or 'to'.
382 data EP a = EP { fromEP :: a, -- :: T -> Tring
383 toEP :: a } -- :: Tring -> T
386 Embedding-projection pairs are used in several places:
388 First of all, each type constructor has an EP associated with it, the
389 code in EP converts (datatype T) from T to Tring and back again.
391 Secondly, when we are filling in Generic methods (in the typechecker,
392 tcMethodBinds), we are constructing bimaps by induction on the structure
393 of the type of the method signature.
396 %************************************************************************
398 \subsection{Occurrence information}
400 %************************************************************************
402 This data type is used exclusively by the simplifier, but it appears in a
403 SubstResult, which is currently defined in VarEnv, which is pretty near
404 the base of the module hierarchy. So it seemed simpler to put the
405 defn of OccInfo here, safely at the bottom
408 -- | Identifier occurrence information
410 = NoOccInfo -- ^ There are many occurrences, or unknown occurences
412 | IAmDead -- ^ Marks unused variables. Sometimes useful for
413 -- lambda and case-bound variables.
418 !InterestingCxt -- ^ Occurs exactly once, not inside a rule
420 -- | This identifier breaks a loop of mutually recursive functions. The field
421 -- marks whether it is only a loop breaker due to a reference in a rule
422 | IAmALoopBreaker -- Note [LoopBreaker OccInfo]
423 !RulesOnly -- True <=> This is a weak or rules-only loop breaker
424 -- See OccurAnal Note [Weak loop breakers]
426 type RulesOnly = Bool
429 Note [LoopBreaker OccInfo]
430 ~~~~~~~~~~~~~~~~~~~~~~~~~~
431 An OccInfo of (IAmLoopBreaker False) is used by the occurrence
432 analyser in two ways:
433 (a) to mark loop-breakers in a group of recursive
434 definitions (hence the name)
435 (b) to mark binders that must not be inlined in this phase
436 (perhaps it has a NOINLINE pragma)
437 Things with (IAmLoopBreaker False) do not get an unfolding
438 pinned on to them, so they are completely opaque.
440 See OccurAnal Note [Weak loop breakers] for (IAmLoopBreaker True).
444 isNoOcc :: OccInfo -> Bool
445 isNoOcc NoOccInfo = True
448 seqOccInfo :: OccInfo -> ()
449 seqOccInfo occ = occ `seq` ()
452 type InterestingCxt = Bool -- True <=> Function: is applied
453 -- Data value: scrutinised by a case with
454 -- at least one non-DEFAULT branch
457 type InsideLam = Bool -- True <=> Occurs inside a non-linear lambda
458 -- Substituting a redex for this occurrence is
459 -- dangerous because it might duplicate work.
460 insideLam, notInsideLam :: InsideLam
465 type OneBranch = Bool -- True <=> Occurs in only one case branch
466 -- so no code-duplication issue to worry about
467 oneBranch, notOneBranch :: OneBranch
471 isLoopBreaker :: OccInfo -> Bool
472 isLoopBreaker (IAmALoopBreaker _) = True
473 isLoopBreaker _ = False
475 isNonRuleLoopBreaker :: OccInfo -> Bool
476 isNonRuleLoopBreaker (IAmALoopBreaker False) = True -- Loop-breaker that breaks a non-rule cycle
477 isNonRuleLoopBreaker _ = False
479 isDeadOcc :: OccInfo -> Bool
480 isDeadOcc IAmDead = True
483 isOneOcc :: OccInfo -> Bool
484 isOneOcc (OneOcc _ _ _) = True
487 isFragileOcc :: OccInfo -> Bool
488 isFragileOcc (OneOcc _ _ _) = True
489 isFragileOcc _ = False
493 instance Outputable OccInfo where
494 -- only used for debugging; never parsed. KSW 1999-07
495 ppr NoOccInfo = empty
496 ppr (IAmALoopBreaker ro) = ptext (sLit "LoopBreaker") <> if ro then char '!' else empty
497 ppr IAmDead = ptext (sLit "Dead")
498 ppr (OneOcc inside_lam one_branch int_cxt)
499 = ptext (sLit "Once") <> pp_lam <> pp_br <> pp_args
501 pp_lam | inside_lam = char 'L'
503 pp_br | one_branch = empty
504 | otherwise = char '*'
505 pp_args | int_cxt = char '!'
508 instance Show OccInfo where
509 showsPrec p occ = showsPrecSDoc p (ppr occ)
512 %************************************************************************
514 \subsection{Strictness indication}
516 %************************************************************************
518 The strictness annotations on types in data type declarations
519 e.g. data T = MkT !Int !(Bool,Bool)
522 data StrictnessMark -- Used in interface decls only
528 isMarkedUnboxed :: StrictnessMark -> Bool
529 isMarkedUnboxed MarkedUnboxed = True
530 isMarkedUnboxed _ = False
532 isMarkedStrict :: StrictnessMark -> Bool
533 isMarkedStrict NotMarkedStrict = False
534 isMarkedStrict _ = True -- All others are strict
536 instance Outputable StrictnessMark where
537 ppr MarkedStrict = ptext (sLit "!")
538 ppr MarkedUnboxed = ptext (sLit "!!")
539 ppr NotMarkedStrict = ptext (sLit "_")
543 %************************************************************************
545 \subsection{Success flag}
547 %************************************************************************
550 data SuccessFlag = Succeeded | Failed
552 instance Outputable SuccessFlag where
553 ppr Succeeded = ptext (sLit "Succeeded")
554 ppr Failed = ptext (sLit "Failed")
556 successIf :: Bool -> SuccessFlag
557 successIf True = Succeeded
558 successIf False = Failed
560 succeeded, failed :: SuccessFlag -> Bool
561 succeeded Succeeded = True
562 succeeded Failed = False
564 failed Succeeded = False
569 %************************************************************************
571 \subsection{Activation}
573 %************************************************************************
575 When a rule or inlining is active
578 type CompilerPhase = Int -- Compilation phase
579 -- Phases decrease towards zero
580 -- Zero is the last phase
582 data Activation = NeverActive
584 | ActiveBefore CompilerPhase -- Active only *before* this phase
585 | ActiveAfter CompilerPhase -- Active in this phase and later
586 deriving( Eq ) -- Eq used in comparing rules in HsDecls
588 data RuleMatchInfo = ConLike
592 isConLike :: RuleMatchInfo -> Bool
593 isConLike ConLike = True
596 isFunLike :: RuleMatchInfo -> Bool
597 isFunLike FunLike = True
602 Activation -- Says during which phases inlining is allowed
603 RuleMatchInfo -- Should the function be treated like a constructor?
606 defaultInlinePragma :: InlinePragma
607 defaultInlinePragma = InlinePragma AlwaysActive FunLike
609 isDefaultInlinePragma :: InlinePragma -> Bool
610 isDefaultInlinePragma (InlinePragma activation match_info)
611 = isAlwaysActive activation && isFunLike match_info
613 inlinePragmaActivation :: InlinePragma -> Activation
614 inlinePragmaActivation (InlinePragma activation _) = activation
616 inlinePragmaRuleMatchInfo :: InlinePragma -> RuleMatchInfo
617 inlinePragmaRuleMatchInfo (InlinePragma _ info) = info
619 setInlinePragmaActivation :: InlinePragma -> Activation -> InlinePragma
620 setInlinePragmaActivation (InlinePragma _ info) activation
621 = InlinePragma activation info
623 setInlinePragmaRuleMatchInfo :: InlinePragma -> RuleMatchInfo -> InlinePragma
624 setInlinePragmaRuleMatchInfo (InlinePragma activation _) info
625 = InlinePragma activation info
630 Bool -- True <=> INLINE
631 -- False <=> NOINLINE
634 defaultInlineSpec :: InlineSpec
635 alwaysInlineSpec, neverInlineSpec :: RuleMatchInfo -> InlineSpec
637 defaultInlineSpec = Inline defaultInlinePragma False
638 -- Inlining is OK, but not forced
639 alwaysInlineSpec match_info
640 = Inline (InlinePragma AlwaysActive match_info) True
642 neverInlineSpec match_info
643 = Inline (InlinePragma NeverActive match_info) False
646 instance Outputable Activation where
647 ppr NeverActive = ptext (sLit "NEVER")
648 ppr AlwaysActive = ptext (sLit "ALWAYS")
649 ppr (ActiveBefore n) = brackets (char '~' <> int n)
650 ppr (ActiveAfter n) = brackets (int n)
652 instance Outputable RuleMatchInfo where
653 ppr ConLike = ptext (sLit "CONLIKE")
654 ppr FunLike = ptext (sLit "FUNLIKE")
656 instance Outputable InlinePragma where
657 ppr (InlinePragma activation FunLike)
659 ppr (InlinePragma activation match_info)
660 = ppr match_info <+> ppr activation
662 instance Outputable InlineSpec where
663 ppr (Inline (InlinePragma act match_info) is_inline)
664 | is_inline = ptext (sLit "INLINE")
667 AlwaysActive -> empty
669 | otherwise = ptext (sLit "NOINLINE")
675 ppr_match_info = if isFunLike match_info then empty else ppr match_info
677 isActive :: CompilerPhase -> Activation -> Bool
678 isActive _ NeverActive = False
679 isActive _ AlwaysActive = True
680 isActive p (ActiveAfter n) = p <= n
681 isActive p (ActiveBefore n) = p > n
683 isNeverActive, isAlwaysActive :: Activation -> Bool
684 isNeverActive NeverActive = True
685 isNeverActive _ = False
687 isAlwaysActive AlwaysActive = True
688 isAlwaysActive _ = False