2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
5 \section[Id]{@Ids@: Value and constructor identifiers}
10 -- GHC uses several kinds of name internally:
12 -- * 'OccName.OccName': see "OccName#name_types"
14 -- * 'RdrName.RdrName': see "RdrName#name_types"
16 -- * 'Name.Name': see "Name#name_types"
18 -- * 'Id.Id' represents names that not only have a 'Name.Name' but also a 'TypeRep.Type' and some additional
19 -- details (a 'IdInfo.IdInfo' and one of 'Var.LocalIdDetails' or 'IdInfo.GlobalIdDetails') that
20 -- are added, modified and inspected by various compiler passes. These 'Var.Var' names may either
21 -- be global or local, see "Var#globalvslocal"
23 -- * 'Var.Var': see "Var#name_types"
28 -- ** Simple construction
29 mkGlobalId, mkVanillaGlobal, mkVanillaGlobalWithInfo,
30 mkLocalId, mkLocalIdWithInfo, mkExportedLocalId,
31 mkSysLocal, mkSysLocalM, mkUserLocal, mkUserLocalM,
32 mkTemplateLocals, mkTemplateLocalsNum, mkTemplateLocal,
35 -- ** Taking an Id apart
36 idName, idType, idUnique, idInfo, idDetails,
38 recordSelectorFieldLabel,
41 setIdName, setIdUnique, Id.setIdType,
42 setIdExported, setIdNotExported,
43 globaliseId, localiseId,
44 setIdInfo, lazySetIdInfo, modifyIdInfo, maybeModifyIdInfo,
45 zapLamIdInfo, zapDemandIdInfo, zapFragileIdInfo, transferPolyIdInfo,
48 -- ** Predicates on Ids
49 isImplicitId, isDeadBinder, isDictId, isStrictId,
50 isExportedId, isLocalId, isGlobalId,
51 isRecordSelector, isNaughtyRecordSelector,
52 isClassOpId_maybe, isDFunId,
53 isPrimOpId, isPrimOpId_maybe,
54 isFCallId, isFCallId_maybe,
55 isDataConWorkId, isDataConWorkId_maybe, isDataConId_maybe, idDataCon,
56 isConLikeId, isBottomingId, idIsFrom,
57 isTickBoxOp, isTickBoxOp_maybe,
60 -- ** Inline pragma stuff
61 idInlinePragma, setInlinePragma, modifyInlinePragma,
62 idInlineActivation, setInlineActivation, idRuleMatchInfo,
64 -- ** One-shot lambdas
65 isOneShotBndr, isOneShotLambda, isStateHackType,
66 setOneShotLambda, clearOneShotLambda,
68 -- ** Reading 'IdInfo' fields
70 idNewDemandInfo, idNewDemandInfo_maybe,
71 idNewStrictness, idNewStrictness_maybe,
74 idSpecialisation, idCoreRules, idHasRules,
85 -- ** Writing 'IdInfo' fields
89 setIdNewStrictness, zapIdNewStrictness,
93 setIdOccInfo, zapIdOccInfo,
102 #include "HsVersions.h"
104 import CoreSyn ( CoreRule, Unfolding )
109 -- Imported and re-exported
110 import Var( Var, Id, DictId,
111 idInfo, idDetails, globaliseId,
112 isId, isLocalId, isGlobalId, isExportedId )
119 #ifdef OLD_STRICTNESS
120 import qualified Demand
138 -- infixl so you can say (id `set` a `set` b)
139 infixl 1 `setIdUnfolding`,
141 `setIdNewDemandInfo`,
142 `setIdNewStrictness`,
144 `setIdSpecialisation`,
147 #ifdef OLD_STRICTNESS
154 %************************************************************************
156 \subsection{Basic Id manipulation}
158 %************************************************************************
164 idUnique :: Id -> Unique
165 idUnique = Var.varUnique
170 idPrimRep :: Id -> PrimRep
171 idPrimRep id = typePrimRep (idType id)
173 setIdName :: Id -> Name -> Id
174 setIdName = Var.setVarName
176 setIdUnique :: Id -> Unique -> Id
177 setIdUnique = Var.setVarUnique
179 -- | Not only does this set the 'Id' 'Type', it also evaluates the type to try and
180 -- reduce space usage
181 setIdType :: Id -> Type -> Id
182 setIdType id ty = seqType ty `seq` Var.setVarType id ty
184 setIdExported :: Id -> Id
185 setIdExported = Var.setIdExported
187 setIdNotExported :: Id -> Id
188 setIdNotExported = Var.setIdNotExported
190 localiseId :: Id -> Id
191 -- Make an with the same unique and type as the
192 -- incoming Id, but with an *Internal* Name and *LocalId* flavour
194 | isLocalId id && isInternalName name
197 = mkLocalIdWithInfo (localiseName name) (idType id) (idInfo id)
201 lazySetIdInfo :: Id -> IdInfo -> Id
202 lazySetIdInfo = Var.lazySetIdInfo
204 setIdInfo :: Id -> IdInfo -> Id
205 setIdInfo id info = seqIdInfo info `seq` (lazySetIdInfo id info)
206 -- Try to avoid spack leaks by seq'ing
208 modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
209 modifyIdInfo fn id = setIdInfo id (fn (idInfo id))
211 -- maybeModifyIdInfo tries to avoid unnecesary thrashing
212 maybeModifyIdInfo :: Maybe IdInfo -> Id -> Id
213 maybeModifyIdInfo (Just new_info) id = lazySetIdInfo id new_info
214 maybeModifyIdInfo Nothing id = id
217 %************************************************************************
219 \subsection{Simple Id construction}
221 %************************************************************************
223 Absolutely all Ids are made by mkId. It is just like Var.mkId,
224 but in addition it pins free-tyvar-info onto the Id's type,
225 where it can easily be found.
227 Note [Free type variables]
228 ~~~~~~~~~~~~~~~~~~~~~~~~~~
229 At one time we cached the free type variables of the type of an Id
230 at the root of the type in a TyNote. The idea was to avoid repeating
231 the free-type-variable calculation. But it turned out to slow down
232 the compiler overall. I don't quite know why; perhaps finding free
233 type variables of an Id isn't all that common whereas applying a
234 substitution (which changes the free type variables) is more common.
235 Anyway, we removed it in March 2008.
238 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
239 mkGlobalId :: IdDetails -> Name -> Type -> IdInfo -> Id
240 mkGlobalId = Var.mkGlobalVar
242 -- | Make a global 'Id' without any extra information at all
243 mkVanillaGlobal :: Name -> Type -> Id
244 mkVanillaGlobal name ty = mkVanillaGlobalWithInfo name ty vanillaIdInfo
246 -- | Make a global 'Id' with no global information but some generic 'IdInfo'
247 mkVanillaGlobalWithInfo :: Name -> Type -> IdInfo -> Id
248 mkVanillaGlobalWithInfo = mkGlobalId VanillaId
251 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
252 mkLocalId :: Name -> Type -> Id
253 mkLocalId name ty = mkLocalIdWithInfo name ty vanillaIdInfo
255 mkLocalIdWithInfo :: Name -> Type -> IdInfo -> Id
256 mkLocalIdWithInfo name ty info = Var.mkLocalVar VanillaId name ty info
257 -- Note [Free type variables]
259 -- | Create a local 'Id' that is marked as exported.
260 -- This prevents things attached to it from being removed as dead code.
261 mkExportedLocalId :: Name -> Type -> Id
262 mkExportedLocalId name ty = Var.mkExportedLocalVar VanillaId name ty vanillaIdInfo
263 -- Note [Free type variables]
266 -- | Create a system local 'Id'. These are local 'Id's (see "Var#globalvslocal")
267 -- that are created by the compiler out of thin air
268 mkSysLocal :: FastString -> Unique -> Type -> Id
269 mkSysLocal fs uniq ty = mkLocalId (mkSystemVarName uniq fs) ty
271 mkSysLocalM :: MonadUnique m => FastString -> Type -> m Id
272 mkSysLocalM fs ty = getUniqueM >>= (\uniq -> return (mkSysLocal fs uniq ty))
275 -- | Create a user local 'Id'. These are local 'Id's (see "Var#globalvslocal") with a name and location that the user might recognize
276 mkUserLocal :: OccName -> Unique -> Type -> SrcSpan -> Id
277 mkUserLocal occ uniq ty loc = mkLocalId (mkInternalName uniq occ loc) ty
279 mkUserLocalM :: MonadUnique m => OccName -> Type -> SrcSpan -> m Id
280 mkUserLocalM occ ty loc = getUniqueM >>= (\uniq -> return (mkUserLocal occ uniq ty loc))
284 Make some local @Ids@ for a template @CoreExpr@. These have bogus
285 @Uniques@, but that's OK because the templates are supposed to be
286 instantiated before use.
289 -- | Workers get local names. "CoreTidy" will externalise these if necessary
290 mkWorkerId :: Unique -> Id -> Type -> Id
291 mkWorkerId uniq unwrkr ty
292 = mkLocalId wkr_name ty
294 wkr_name = mkInternalName uniq (mkWorkerOcc (getOccName unwrkr)) (getSrcSpan unwrkr)
296 -- | Create a /template local/: a family of system local 'Id's in bijection with @Int@s, typically used in unfoldings
297 mkTemplateLocal :: Int -> Type -> Id
298 mkTemplateLocal i ty = mkSysLocal (fsLit "tpl") (mkBuiltinUnique i) ty
300 -- | Create a template local for a series of types
301 mkTemplateLocals :: [Type] -> [Id]
302 mkTemplateLocals = mkTemplateLocalsNum 1
304 -- | Create a template local for a series of type, but start from a specified template local
305 mkTemplateLocalsNum :: Int -> [Type] -> [Id]
306 mkTemplateLocalsNum n tys = zipWith mkTemplateLocal [n..] tys
310 %************************************************************************
312 \subsection{Special Ids}
314 %************************************************************************
317 -- | If the 'Id' is that for a record selector, extract the 'sel_tycon' and label. Panic otherwise
318 recordSelectorFieldLabel :: Id -> (TyCon, FieldLabel)
319 recordSelectorFieldLabel id
320 = case Var.idDetails id of
321 RecSelId { sel_tycon = tycon } -> (tycon, idName id)
322 _ -> panic "recordSelectorFieldLabel"
324 isRecordSelector :: Id -> Bool
325 isNaughtyRecordSelector :: Id -> Bool
326 isPrimOpId :: Id -> Bool
327 isFCallId :: Id -> Bool
328 isDataConWorkId :: Id -> Bool
329 isDFunId :: Id -> Bool
331 isClassOpId_maybe :: Id -> Maybe Class
332 isPrimOpId_maybe :: Id -> Maybe PrimOp
333 isFCallId_maybe :: Id -> Maybe ForeignCall
334 isDataConWorkId_maybe :: Id -> Maybe DataCon
336 isRecordSelector id = case Var.idDetails id of
340 isNaughtyRecordSelector id = case Var.idDetails id of
341 RecSelId { sel_naughty = n } -> n
344 isClassOpId_maybe id = case Var.idDetails id of
345 ClassOpId cls -> Just cls
348 isPrimOpId id = case Var.idDetails id of
352 isDFunId id = case Var.idDetails id of
356 isPrimOpId_maybe id = case Var.idDetails id of
357 PrimOpId op -> Just op
360 isFCallId id = case Var.idDetails id of
364 isFCallId_maybe id = case Var.idDetails id of
365 FCallId call -> Just call
368 isDataConWorkId id = case Var.idDetails id of
369 DataConWorkId _ -> True
372 isDataConWorkId_maybe id = case Var.idDetails id of
373 DataConWorkId con -> Just con
376 isDataConId_maybe :: Id -> Maybe DataCon
377 isDataConId_maybe id = case Var.idDetails id of
378 DataConWorkId con -> Just con
379 DataConWrapId con -> Just con
382 idDataCon :: Id -> DataCon
383 -- ^ Get from either the worker or the wrapper 'Id' to the 'DataCon'. Currently used only in the desugarer.
385 -- INVARIANT: @idDataCon (dataConWrapId d) = d@: remember, 'dataConWrapId' can return either the wrapper or the worker
386 idDataCon id = isDataConId_maybe id `orElse` pprPanic "idDataCon" (ppr id)
389 isDictId :: Id -> Bool
390 isDictId id = isDictTy (idType id)
392 hasNoBinding :: Id -> Bool
393 -- ^ Returns @True@ of an 'Id' which may not have a
394 -- binding, even though it is defined in this module.
396 -- Data constructor workers used to be things of this kind, but
397 -- they aren't any more. Instead, we inject a binding for
398 -- them at the CorePrep stage.
399 -- EXCEPT: unboxed tuples, which definitely have no binding
400 hasNoBinding id = case Var.idDetails id of
401 PrimOpId _ -> True -- See Note [Primop wrappers]
403 DataConWorkId dc -> isUnboxedTupleCon dc
406 isImplicitId :: Id -> Bool
407 -- ^ 'isImplicitId' tells whether an 'Id's info is implied by other
408 -- declarations, so we don't need to put its signature in an interface
409 -- file, even if it's mentioned in some other interface unfolding.
411 = case Var.idDetails id of
415 DataConWorkId _ -> True
416 DataConWrapId _ -> True
417 -- These are are implied by their type or class decl;
418 -- remember that all type and class decls appear in the interface file.
419 -- The dfun id is not an implicit Id; it must *not* be omitted, because
420 -- it carries version info for the instance decl
423 idIsFrom :: Module -> Id -> Bool
424 idIsFrom mod id = nameIsLocalOrFrom mod (idName id)
427 Note [Primop wrappers]
428 ~~~~~~~~~~~~~~~~~~~~~~
429 Currently hasNoBinding claims that PrimOpIds don't have a curried
430 function definition. But actually they do, in GHC.PrimopWrappers,
431 which is auto-generated from prelude/primops.txt.pp. So actually, hasNoBinding
432 could return 'False' for PrimOpIds.
434 But we'd need to add something in CoreToStg to swizzle any unsaturated
435 applications of GHC.Prim.plusInt# to GHC.PrimopWrappers.plusInt#.
437 Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's
438 used by GHCi, which does not implement primops direct at all.
443 isDeadBinder :: Id -> Bool
444 isDeadBinder bndr | isId bndr = isDeadOcc (idOccInfo bndr)
445 | otherwise = False -- TyVars count as not dead
449 isTickBoxOp :: Id -> Bool
451 case Var.idDetails id of
452 TickBoxOpId _ -> True
455 isTickBoxOp_maybe :: Id -> Maybe TickBoxOp
456 isTickBoxOp_maybe id =
457 case Var.idDetails id of
458 TickBoxOpId tick -> Just tick
462 %************************************************************************
464 \subsection{IdInfo stuff}
466 %************************************************************************
469 ---------------------------------
471 idArity :: Id -> Arity
472 idArity id = arityInfo (idInfo id)
474 setIdArity :: Id -> Arity -> Id
475 setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
477 #ifdef OLD_STRICTNESS
478 ---------------------------------
480 idStrictness :: Id -> StrictnessInfo
481 idStrictness id = strictnessInfo (idInfo id)
483 setIdStrictness :: Id -> StrictnessInfo -> Id
484 setIdStrictness id strict_info = modifyIdInfo (`setStrictnessInfo` strict_info) id
487 -- | Returns true if an application to n args would diverge
488 isBottomingId :: Id -> Bool
489 isBottomingId id = isBottomingSig (idNewStrictness id)
491 idNewStrictness_maybe :: Id -> Maybe StrictSig
492 idNewStrictness :: Id -> StrictSig
494 idNewStrictness_maybe id = newStrictnessInfo (idInfo id)
495 idNewStrictness id = idNewStrictness_maybe id `orElse` topSig
497 setIdNewStrictness :: Id -> StrictSig -> Id
498 setIdNewStrictness id sig = modifyIdInfo (`setNewStrictnessInfo` Just sig) id
500 zapIdNewStrictness :: Id -> Id
501 zapIdNewStrictness id = modifyIdInfo (`setNewStrictnessInfo` Nothing) id
503 -- | This predicate says whether the 'Id' has a strict demand placed on it or
504 -- has a type such that it can always be evaluated strictly (e.g., an
505 -- unlifted type, but see the comment for 'isStrictType'). We need to
506 -- check separately whether the 'Id' has a so-called \"strict type\" because if
507 -- the demand for the given @id@ hasn't been computed yet but @id@ has a strict
508 -- type, we still want @isStrictId id@ to be @True@.
509 isStrictId :: Id -> Bool
511 = ASSERT2( isId id, text "isStrictId: not an id: " <+> ppr id )
512 (isStrictDmd (idNewDemandInfo id)) ||
513 (isStrictType (idType id))
515 ---------------------------------
517 idWorkerInfo :: Id -> WorkerInfo
518 idWorkerInfo id = workerInfo (idInfo id)
520 setIdWorkerInfo :: Id -> WorkerInfo -> Id
521 setIdWorkerInfo id work_info = modifyIdInfo (`setWorkerInfo` work_info) id
523 ---------------------------------
525 idUnfolding :: Id -> Unfolding
526 idUnfolding id = unfoldingInfo (idInfo id)
528 setIdUnfolding :: Id -> Unfolding -> Id
529 setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
531 #ifdef OLD_STRICTNESS
532 ---------------------------------
534 idDemandInfo :: Id -> Demand.Demand
535 idDemandInfo id = demandInfo (idInfo id)
537 setIdDemandInfo :: Id -> Demand.Demand -> Id
538 setIdDemandInfo id demand_info = modifyIdInfo (`setDemandInfo` demand_info) id
541 idNewDemandInfo_maybe :: Id -> Maybe NewDemand.Demand
542 idNewDemandInfo :: Id -> NewDemand.Demand
544 idNewDemandInfo_maybe id = newDemandInfo (idInfo id)
545 idNewDemandInfo id = newDemandInfo (idInfo id) `orElse` NewDemand.topDmd
547 setIdNewDemandInfo :: Id -> NewDemand.Demand -> Id
548 setIdNewDemandInfo id dmd = modifyIdInfo (`setNewDemandInfo` Just dmd) id
550 ---------------------------------
552 idSpecialisation :: Id -> SpecInfo
553 idSpecialisation id = specInfo (idInfo id)
555 idCoreRules :: Id -> [CoreRule]
556 idCoreRules id = specInfoRules (idSpecialisation id)
558 idHasRules :: Id -> Bool
559 idHasRules id = not (isEmptySpecInfo (idSpecialisation id))
561 setIdSpecialisation :: Id -> SpecInfo -> Id
562 setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
564 ---------------------------------
566 idCafInfo :: Id -> CafInfo
567 #ifdef OLD_STRICTNESS
568 idCafInfo id = case cgInfo (idInfo id) of
569 NoCgInfo -> pprPanic "idCafInfo" (ppr id)
570 info -> cgCafInfo info
572 idCafInfo id = cafInfo (idInfo id)
575 setIdCafInfo :: Id -> CafInfo -> Id
576 setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
578 ---------------------------------
580 #ifdef OLD_STRICTNESS
581 idCprInfo :: Id -> CprInfo
582 idCprInfo id = cprInfo (idInfo id)
584 setIdCprInfo :: Id -> CprInfo -> Id
585 setIdCprInfo id cpr_info = modifyIdInfo (`setCprInfo` cpr_info) id
588 ---------------------------------
590 idOccInfo :: Id -> OccInfo
591 idOccInfo id = occInfo (idInfo id)
593 setIdOccInfo :: Id -> OccInfo -> Id
594 setIdOccInfo id occ_info = modifyIdInfo (`setOccInfo` occ_info) id
596 zapIdOccInfo :: Id -> Id
597 zapIdOccInfo b = b `setIdOccInfo` NoOccInfo
601 ---------------------------------
603 The inline pragma tells us to be very keen to inline this Id, but it's still
604 OK not to if optimisation is switched off.
607 idInlinePragma :: Id -> InlinePragma
608 idInlinePragma id = inlinePragInfo (idInfo id)
610 setInlinePragma :: Id -> InlinePragma -> Id
611 setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
613 modifyInlinePragma :: Id -> (InlinePragma -> InlinePragma) -> Id
614 modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
616 idInlineActivation :: Id -> Activation
617 idInlineActivation id = inlinePragmaActivation (idInlinePragma id)
619 setInlineActivation :: Id -> Activation -> Id
620 setInlineActivation id act = modifyInlinePragma id (\(InlinePragma _ match_info) -> InlinePragma act match_info)
622 idRuleMatchInfo :: Id -> RuleMatchInfo
623 idRuleMatchInfo id = inlinePragmaRuleMatchInfo (idInlinePragma id)
625 isConLikeId :: Id -> Bool
626 isConLikeId id = isDataConWorkId id || isConLike (idRuleMatchInfo id)
630 ---------------------------------
633 idLBVarInfo :: Id -> LBVarInfo
634 idLBVarInfo id = lbvarInfo (idInfo id)
636 -- | Returns whether the lambda associated with the 'Id' is certainly applied at most once
637 -- OR we are applying the \"state hack\" which makes it appear as if theis is the case for
638 -- lambdas used in @IO@. You should prefer using this over 'isOneShotLambda'
639 isOneShotBndr :: Id -> Bool
640 -- This one is the "business end", called externally.
641 -- Its main purpose is to encapsulate the Horrible State Hack
642 isOneShotBndr id = isOneShotLambda id || isStateHackType (idType id)
644 -- | Should we apply the state hack to values of this 'Type'?
645 isStateHackType :: Type -> Bool
650 = case splitTyConApp_maybe ty of
651 Just (tycon,_) -> tycon == statePrimTyCon
653 -- This is a gross hack. It claims that
654 -- every function over realWorldStatePrimTy is a one-shot
655 -- function. This is pretty true in practice, and makes a big
656 -- difference. For example, consider
657 -- a `thenST` \ r -> ...E...
658 -- The early full laziness pass, if it doesn't know that r is one-shot
659 -- will pull out E (let's say it doesn't mention r) to give
660 -- let lvl = E in a `thenST` \ r -> ...lvl...
661 -- When `thenST` gets inlined, we end up with
662 -- let lvl = E in \s -> case a s of (r, s') -> ...lvl...
663 -- and we don't re-inline E.
665 -- It would be better to spot that r was one-shot to start with, but
666 -- I don't want to rely on that.
668 -- Another good example is in fill_in in PrelPack.lhs. We should be able to
669 -- spot that fill_in has arity 2 (and when Keith is done, we will) but we can't yet.
672 -- | Returns whether the lambda associated with the 'Id' is certainly applied at most once.
673 -- You probably want to use 'isOneShotBndr' instead
674 isOneShotLambda :: Id -> Bool
675 isOneShotLambda id = case idLBVarInfo id of
676 IsOneShotLambda -> True
679 setOneShotLambda :: Id -> Id
680 setOneShotLambda id = modifyIdInfo (`setLBVarInfo` IsOneShotLambda) id
682 clearOneShotLambda :: Id -> Id
683 clearOneShotLambda id
684 | isOneShotLambda id = modifyIdInfo (`setLBVarInfo` NoLBVarInfo) id
687 -- The OneShotLambda functions simply fiddle with the IdInfo flag
688 -- But watch out: this may change the type of something else
690 -- If we change the one-shot-ness of x, f's type changes
694 zapInfo :: (IdInfo -> Maybe IdInfo) -> Id -> Id
695 zapInfo zapper id = maybeModifyIdInfo (zapper (idInfo id)) id
697 zapLamIdInfo :: Id -> Id
698 zapLamIdInfo = zapInfo zapLamInfo
700 zapDemandIdInfo :: Id -> Id
701 zapDemandIdInfo = zapInfo zapDemandInfo
703 zapFragileIdInfo :: Id -> Id
704 zapFragileIdInfo = zapInfo zapFragileInfo
707 Note [transferPolyIdInfo]
708 ~~~~~~~~~~~~~~~~~~~~~~~~~
711 f = /\a. let g = rhs in ...
713 where g has interesting strictness information. Then if we float thus
718 we *do not* want to lose g's
719 * strictness information
721 * inline pragma (though that is bit more debatable)
723 It's simple to retain strictness and arity, but not so simple to retain
726 so we simply discard those. Sooner or later this may bite us.
728 This transfer is used in two places:
729 FloatOut (long-distance let-floating)
730 SimplUtils.abstractFloats (short-distance let-floating)
732 If we abstract wrt one or more *value* binders, we must modify the
733 arity and strictness info before transferring it. E.g.
737 + substitute (g' y) for g
738 Notice that g' has an arity one more than the original g
741 transferPolyIdInfo :: Id -- Original Id
742 -> [Var] -- Abstract wrt these variables
745 transferPolyIdInfo old_id abstract_wrt new_id
746 = modifyIdInfo transfer new_id
748 arity_increase = count isId abstract_wrt -- Arity increases by the
749 -- number of value binders
751 old_info = idInfo old_id
752 old_arity = arityInfo old_info
753 old_inline_prag = inlinePragInfo old_info
754 new_arity = old_arity + arity_increase
755 old_strictness = newStrictnessInfo old_info
756 new_strictness = fmap (increaseStrictSigArity arity_increase) old_strictness
758 transfer new_info = new_info `setNewStrictnessInfo` new_strictness
759 `setArityInfo` new_arity
760 `setInlinePragInfo` old_inline_prag