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,
33 mkWorkerId, mkWiredInIdName,
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 idDemandInfo, idDemandInfo_maybe,
71 idStrictness, idStrictness_maybe,
72 idUnfolding, realIdUnfolding,
73 idSpecialisation, idCoreRules, idHasRules,
78 -- ** Writing 'IdInfo' fields
83 setIdStrictness, zapIdStrictness,
86 setIdOccInfo, zapIdOccInfo,
90 #include "HsVersions.h"
92 import CoreSyn ( CoreRule, Unfolding( NoUnfolding ) )
97 -- Imported and re-exported
98 import Var( Var, Id, DictId,
99 idInfo, idDetails, globaliseId,
100 isId, isLocalId, isGlobalId, isExportedId )
122 -- infixl so you can say (id `set` a `set` b)
123 infixl 1 `setIdUnfoldingLazily`,
129 `setIdSpecialisation`,
131 `setInlineActivation`,
135 %************************************************************************
137 \subsection{Basic Id manipulation}
139 %************************************************************************
145 idUnique :: Id -> Unique
146 idUnique = Var.varUnique
151 idPrimRep :: Id -> PrimRep
152 idPrimRep id = typePrimRep (idType id)
154 setIdName :: Id -> Name -> Id
155 setIdName = Var.setVarName
157 setIdUnique :: Id -> Unique -> Id
158 setIdUnique = Var.setVarUnique
160 -- | Not only does this set the 'Id' 'Type', it also evaluates the type to try and
161 -- reduce space usage
162 setIdType :: Id -> Type -> Id
163 setIdType id ty = seqType ty `seq` Var.setVarType id ty
165 setIdExported :: Id -> Id
166 setIdExported = Var.setIdExported
168 setIdNotExported :: Id -> Id
169 setIdNotExported = Var.setIdNotExported
171 localiseId :: Id -> Id
172 -- Make an with the same unique and type as the
173 -- incoming Id, but with an *Internal* Name and *LocalId* flavour
175 | ASSERT( isId id ) isLocalId id && isInternalName name
178 = mkLocalIdWithInfo (localiseName name) (idType id) (idInfo id)
182 lazySetIdInfo :: Id -> IdInfo -> Id
183 lazySetIdInfo = Var.lazySetIdInfo
185 setIdInfo :: Id -> IdInfo -> Id
186 setIdInfo id info = seqIdInfo info `seq` (lazySetIdInfo id info)
187 -- Try to avoid spack leaks by seq'ing
189 modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
190 modifyIdInfo fn id = setIdInfo id (fn (idInfo id))
192 -- maybeModifyIdInfo tries to avoid unnecesary thrashing
193 maybeModifyIdInfo :: Maybe IdInfo -> Id -> Id
194 maybeModifyIdInfo (Just new_info) id = lazySetIdInfo id new_info
195 maybeModifyIdInfo Nothing id = id
198 %************************************************************************
200 \subsection{Simple Id construction}
202 %************************************************************************
204 Absolutely all Ids are made by mkId. It is just like Var.mkId,
205 but in addition it pins free-tyvar-info onto the Id's type,
206 where it can easily be found.
208 Note [Free type variables]
209 ~~~~~~~~~~~~~~~~~~~~~~~~~~
210 At one time we cached the free type variables of the type of an Id
211 at the root of the type in a TyNote. The idea was to avoid repeating
212 the free-type-variable calculation. But it turned out to slow down
213 the compiler overall. I don't quite know why; perhaps finding free
214 type variables of an Id isn't all that common whereas applying a
215 substitution (which changes the free type variables) is more common.
216 Anyway, we removed it in March 2008.
219 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
220 mkGlobalId :: IdDetails -> Name -> Type -> IdInfo -> Id
221 mkGlobalId = Var.mkGlobalVar
223 -- | Make a global 'Id' without any extra information at all
224 mkVanillaGlobal :: Name -> Type -> Id
225 mkVanillaGlobal name ty = mkVanillaGlobalWithInfo name ty vanillaIdInfo
227 -- | Make a global 'Id' with no global information but some generic 'IdInfo'
228 mkVanillaGlobalWithInfo :: Name -> Type -> IdInfo -> Id
229 mkVanillaGlobalWithInfo = mkGlobalId VanillaId
232 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
233 mkLocalId :: Name -> Type -> Id
234 mkLocalId name ty = mkLocalIdWithInfo name ty vanillaIdInfo
236 mkLocalIdWithInfo :: Name -> Type -> IdInfo -> Id
237 mkLocalIdWithInfo name ty info = Var.mkLocalVar VanillaId name ty info
238 -- Note [Free type variables]
240 -- | Create a local 'Id' that is marked as exported.
241 -- This prevents things attached to it from being removed as dead code.
242 mkExportedLocalId :: Name -> Type -> Id
243 mkExportedLocalId name ty = Var.mkExportedLocalVar VanillaId name ty vanillaIdInfo
244 -- Note [Free type variables]
247 -- | Create a system local 'Id'. These are local 'Id's (see "Var#globalvslocal")
248 -- that are created by the compiler out of thin air
249 mkSysLocal :: FastString -> Unique -> Type -> Id
250 mkSysLocal fs uniq ty = mkLocalId (mkSystemVarName uniq fs) ty
252 mkSysLocalM :: MonadUnique m => FastString -> Type -> m Id
253 mkSysLocalM fs ty = getUniqueM >>= (\uniq -> return (mkSysLocal fs uniq ty))
256 -- | Create a user local 'Id'. These are local 'Id's (see "Var#globalvslocal") with a name and location that the user might recognize
257 mkUserLocal :: OccName -> Unique -> Type -> SrcSpan -> Id
258 mkUserLocal occ uniq ty loc = mkLocalId (mkInternalName uniq occ loc) ty
260 mkUserLocalM :: MonadUnique m => OccName -> Type -> SrcSpan -> m Id
261 mkUserLocalM occ ty loc = getUniqueM >>= (\uniq -> return (mkUserLocal occ uniq ty loc))
263 mkWiredInIdName :: Module -> FastString -> Unique -> Id -> Name
264 mkWiredInIdName mod fs uniq id
265 = mkWiredInName mod (mkOccNameFS varName fs) uniq (AnId id) UserSyntax
268 Make some local @Ids@ for a template @CoreExpr@. These have bogus
269 @Uniques@, but that's OK because the templates are supposed to be
270 instantiated before use.
273 -- | Workers get local names. "CoreTidy" will externalise these if necessary
274 mkWorkerId :: Unique -> Id -> Type -> Id
275 mkWorkerId uniq unwrkr ty
276 = mkLocalId (mkDerivedInternalName mkWorkerOcc uniq (getName unwrkr)) ty
278 -- | Create a /template local/: a family of system local 'Id's in bijection with @Int@s, typically used in unfoldings
279 mkTemplateLocal :: Int -> Type -> Id
280 mkTemplateLocal i ty = mkSysLocal (fsLit "tpl") (mkBuiltinUnique i) ty
282 -- | Create a template local for a series of types
283 mkTemplateLocals :: [Type] -> [Id]
284 mkTemplateLocals = mkTemplateLocalsNum 1
286 -- | Create a template local for a series of type, but start from a specified template local
287 mkTemplateLocalsNum :: Int -> [Type] -> [Id]
288 mkTemplateLocalsNum n tys = zipWith mkTemplateLocal [n..] tys
292 %************************************************************************
294 \subsection{Special Ids}
296 %************************************************************************
299 -- | If the 'Id' is that for a record selector, extract the 'sel_tycon' and label. Panic otherwise
300 recordSelectorFieldLabel :: Id -> (TyCon, FieldLabel)
301 recordSelectorFieldLabel id
302 = case Var.idDetails id of
303 RecSelId { sel_tycon = tycon } -> (tycon, idName id)
304 _ -> panic "recordSelectorFieldLabel"
306 isRecordSelector :: Id -> Bool
307 isNaughtyRecordSelector :: Id -> Bool
308 isPrimOpId :: Id -> Bool
309 isFCallId :: Id -> Bool
310 isDataConWorkId :: Id -> Bool
311 isDFunId :: Id -> Bool
313 isClassOpId_maybe :: Id -> Maybe Class
314 isPrimOpId_maybe :: Id -> Maybe PrimOp
315 isFCallId_maybe :: Id -> Maybe ForeignCall
316 isDataConWorkId_maybe :: Id -> Maybe DataCon
318 isRecordSelector id = case Var.idDetails id of
322 isNaughtyRecordSelector id = case Var.idDetails id of
323 RecSelId { sel_naughty = n } -> n
326 isClassOpId_maybe id = case Var.idDetails id of
327 ClassOpId cls -> Just cls
330 isPrimOpId id = case Var.idDetails id of
334 isDFunId id = case Var.idDetails id of
338 isPrimOpId_maybe id = case Var.idDetails id of
339 PrimOpId op -> Just op
342 isFCallId id = case Var.idDetails id of
346 isFCallId_maybe id = case Var.idDetails id of
347 FCallId call -> Just call
350 isDataConWorkId id = case Var.idDetails id of
351 DataConWorkId _ -> True
354 isDataConWorkId_maybe id = case Var.idDetails id of
355 DataConWorkId con -> Just con
358 isDataConId_maybe :: Id -> Maybe DataCon
359 isDataConId_maybe id = case Var.idDetails id of
360 DataConWorkId con -> Just con
361 DataConWrapId con -> Just con
364 idDataCon :: Id -> DataCon
365 -- ^ Get from either the worker or the wrapper 'Id' to the 'DataCon'. Currently used only in the desugarer.
367 -- INVARIANT: @idDataCon (dataConWrapId d) = d@: remember, 'dataConWrapId' can return either the wrapper or the worker
368 idDataCon id = isDataConId_maybe id `orElse` pprPanic "idDataCon" (ppr id)
371 isDictId :: Id -> Bool
372 isDictId id = isDictTy (idType id)
374 hasNoBinding :: Id -> Bool
375 -- ^ Returns @True@ of an 'Id' which may not have a
376 -- binding, even though it is defined in this module.
378 -- Data constructor workers used to be things of this kind, but
379 -- they aren't any more. Instead, we inject a binding for
380 -- them at the CorePrep stage.
381 -- EXCEPT: unboxed tuples, which definitely have no binding
382 hasNoBinding id = case Var.idDetails id of
383 PrimOpId _ -> True -- See Note [Primop wrappers]
385 DataConWorkId dc -> isUnboxedTupleCon dc
388 isImplicitId :: Id -> Bool
389 -- ^ 'isImplicitId' tells whether an 'Id's info is implied by other
390 -- declarations, so we don't need to put its signature in an interface
391 -- file, even if it's mentioned in some other interface unfolding.
393 = case Var.idDetails id of
397 DataConWorkId {} -> True
398 DataConWrapId {} -> True
399 -- These are are implied by their type or class decl;
400 -- remember that all type and class decls appear in the interface file.
401 -- The dfun id is not an implicit Id; it must *not* be omitted, because
402 -- it carries version info for the instance decl
405 idIsFrom :: Module -> Id -> Bool
406 idIsFrom mod id = nameIsLocalOrFrom mod (idName id)
409 Note [Primop wrappers]
410 ~~~~~~~~~~~~~~~~~~~~~~
411 Currently hasNoBinding claims that PrimOpIds don't have a curried
412 function definition. But actually they do, in GHC.PrimopWrappers,
413 which is auto-generated from prelude/primops.txt.pp. So actually, hasNoBinding
414 could return 'False' for PrimOpIds.
416 But we'd need to add something in CoreToStg to swizzle any unsaturated
417 applications of GHC.Prim.plusInt# to GHC.PrimopWrappers.plusInt#.
419 Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's
420 used by GHCi, which does not implement primops direct at all.
425 isDeadBinder :: Id -> Bool
426 isDeadBinder bndr | isId bndr = isDeadOcc (idOccInfo bndr)
427 | otherwise = False -- TyVars count as not dead
431 isTickBoxOp :: Id -> Bool
433 case Var.idDetails id of
434 TickBoxOpId _ -> True
437 isTickBoxOp_maybe :: Id -> Maybe TickBoxOp
438 isTickBoxOp_maybe id =
439 case Var.idDetails id of
440 TickBoxOpId tick -> Just tick
444 %************************************************************************
446 \subsection{IdInfo stuff}
448 %************************************************************************
451 ---------------------------------
453 idArity :: Id -> Arity
454 idArity id = arityInfo (idInfo id)
456 setIdArity :: Id -> Arity -> Id
457 setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
459 -- | Returns true if an application to n args would diverge
460 isBottomingId :: Id -> Bool
461 isBottomingId id = isBottomingSig (idStrictness id)
463 idStrictness_maybe :: Id -> Maybe StrictSig
464 idStrictness :: Id -> StrictSig
466 idStrictness_maybe id = strictnessInfo (idInfo id)
467 idStrictness id = idStrictness_maybe id `orElse` topSig
469 setIdStrictness :: Id -> StrictSig -> Id
470 setIdStrictness id sig = modifyIdInfo (`setStrictnessInfo` Just sig) id
472 zapIdStrictness :: Id -> Id
473 zapIdStrictness id = modifyIdInfo (`setStrictnessInfo` Nothing) id
475 -- | This predicate says whether the 'Id' has a strict demand placed on it or
476 -- has a type such that it can always be evaluated strictly (e.g., an
477 -- unlifted type, but see the comment for 'isStrictType'). We need to
478 -- check separately whether the 'Id' has a so-called \"strict type\" because if
479 -- the demand for the given @id@ hasn't been computed yet but @id@ has a strict
480 -- type, we still want @isStrictId id@ to be @True@.
481 isStrictId :: Id -> Bool
483 = ASSERT2( isId id, text "isStrictId: not an id: " <+> ppr id )
484 (isStrictDmd (idDemandInfo id)) ||
485 (isStrictType (idType id))
487 ---------------------------------
489 idUnfolding :: Id -> Unfolding
490 -- Do not expose the unfolding of a loop breaker!
492 | isNonRuleLoopBreaker (occInfo info) = NoUnfolding
493 | otherwise = unfoldingInfo info
497 realIdUnfolding :: Id -> Unfolding
498 -- Expose the unfolding if there is one, including for loop breakers
499 realIdUnfolding id = unfoldingInfo (idInfo id)
501 setIdUnfoldingLazily :: Id -> Unfolding -> Id
502 setIdUnfoldingLazily id unfolding = modifyIdInfo (`setUnfoldingInfoLazily` unfolding) id
504 setIdUnfolding :: Id -> Unfolding -> Id
505 setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
507 idDemandInfo_maybe :: Id -> Maybe Demand
508 idDemandInfo :: Id -> Demand
510 idDemandInfo_maybe id = demandInfo (idInfo id)
511 idDemandInfo id = demandInfo (idInfo id) `orElse` topDmd
513 setIdDemandInfo :: Id -> Demand -> Id
514 setIdDemandInfo id dmd = modifyIdInfo (`setDemandInfo` Just dmd) id
516 ---------------------------------
519 -- See Note [Specialisations and RULES in IdInfo] in IdInfo.lhs
521 idSpecialisation :: Id -> SpecInfo
522 idSpecialisation id = specInfo (idInfo id)
524 idCoreRules :: Id -> [CoreRule]
525 idCoreRules id = specInfoRules (idSpecialisation id)
527 idHasRules :: Id -> Bool
528 idHasRules id = not (isEmptySpecInfo (idSpecialisation id))
530 setIdSpecialisation :: Id -> SpecInfo -> Id
531 setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
533 ---------------------------------
535 idCafInfo :: Id -> CafInfo
536 idCafInfo id = cafInfo (idInfo id)
538 setIdCafInfo :: Id -> CafInfo -> Id
539 setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
541 ---------------------------------
543 idOccInfo :: Id -> OccInfo
544 idOccInfo id = occInfo (idInfo id)
546 setIdOccInfo :: Id -> OccInfo -> Id
547 setIdOccInfo id occ_info = modifyIdInfo (`setOccInfo` occ_info) id
549 zapIdOccInfo :: Id -> Id
550 zapIdOccInfo b = b `setIdOccInfo` NoOccInfo
554 ---------------------------------
556 The inline pragma tells us to be very keen to inline this Id, but it's still
557 OK not to if optimisation is switched off.
560 idInlinePragma :: Id -> InlinePragma
561 idInlinePragma id = inlinePragInfo (idInfo id)
563 setInlinePragma :: Id -> InlinePragma -> Id
564 setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
566 modifyInlinePragma :: Id -> (InlinePragma -> InlinePragma) -> Id
567 modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
569 idInlineActivation :: Id -> Activation
570 idInlineActivation id = inlinePragmaActivation (idInlinePragma id)
572 setInlineActivation :: Id -> Activation -> Id
573 setInlineActivation id act = modifyInlinePragma id (\prag -> setInlinePragmaActivation prag act)
575 idRuleMatchInfo :: Id -> RuleMatchInfo
576 idRuleMatchInfo id = inlinePragmaRuleMatchInfo (idInlinePragma id)
578 isConLikeId :: Id -> Bool
579 isConLikeId id = isDataConWorkId id || isConLike (idRuleMatchInfo id)
583 ---------------------------------
586 idLBVarInfo :: Id -> LBVarInfo
587 idLBVarInfo id = lbvarInfo (idInfo id)
589 -- | Returns whether the lambda associated with the 'Id' is certainly applied at most once
590 -- OR we are applying the \"state hack\" which makes it appear as if theis is the case for
591 -- lambdas used in @IO@. You should prefer using this over 'isOneShotLambda'
592 isOneShotBndr :: Id -> Bool
593 -- This one is the "business end", called externally.
594 -- Its main purpose is to encapsulate the Horrible State Hack
595 isOneShotBndr id = isOneShotLambda id || isStateHackType (idType id)
597 -- | Should we apply the state hack to values of this 'Type'?
598 isStateHackType :: Type -> Bool
603 = case splitTyConApp_maybe ty of
604 Just (tycon,_) -> tycon == statePrimTyCon
606 -- This is a gross hack. It claims that
607 -- every function over realWorldStatePrimTy is a one-shot
608 -- function. This is pretty true in practice, and makes a big
609 -- difference. For example, consider
610 -- a `thenST` \ r -> ...E...
611 -- The early full laziness pass, if it doesn't know that r is one-shot
612 -- will pull out E (let's say it doesn't mention r) to give
613 -- let lvl = E in a `thenST` \ r -> ...lvl...
614 -- When `thenST` gets inlined, we end up with
615 -- let lvl = E in \s -> case a s of (r, s') -> ...lvl...
616 -- and we don't re-inline E.
618 -- It would be better to spot that r was one-shot to start with, but
619 -- I don't want to rely on that.
621 -- Another good example is in fill_in in PrelPack.lhs. We should be able to
622 -- spot that fill_in has arity 2 (and when Keith is done, we will) but we can't yet.
625 -- | Returns whether the lambda associated with the 'Id' is certainly applied at most once.
626 -- You probably want to use 'isOneShotBndr' instead
627 isOneShotLambda :: Id -> Bool
628 isOneShotLambda id = case idLBVarInfo id of
629 IsOneShotLambda -> True
632 setOneShotLambda :: Id -> Id
633 setOneShotLambda id = modifyIdInfo (`setLBVarInfo` IsOneShotLambda) id
635 clearOneShotLambda :: Id -> Id
636 clearOneShotLambda id
637 | isOneShotLambda id = modifyIdInfo (`setLBVarInfo` NoLBVarInfo) id
640 -- The OneShotLambda functions simply fiddle with the IdInfo flag
641 -- But watch out: this may change the type of something else
643 -- If we change the one-shot-ness of x, f's type changes
647 zapInfo :: (IdInfo -> Maybe IdInfo) -> Id -> Id
648 zapInfo zapper id = maybeModifyIdInfo (zapper (idInfo id)) id
650 zapLamIdInfo :: Id -> Id
651 zapLamIdInfo = zapInfo zapLamInfo
653 zapDemandIdInfo :: Id -> Id
654 zapDemandIdInfo = zapInfo zapDemandInfo
656 zapFragileIdInfo :: Id -> Id
657 zapFragileIdInfo = zapInfo zapFragileInfo
660 Note [transferPolyIdInfo]
661 ~~~~~~~~~~~~~~~~~~~~~~~~~
662 This transfer is used in two places:
663 FloatOut (long-distance let-floating)
664 SimplUtils.abstractFloats (short-distance let-floating)
666 Consider the short-distance let-floating:
668 f = /\a. let g = rhs in ...
670 Then if we float thus
673 f = /\a. ...[g' a/g]....
675 we *do not* want to lose g's
676 * strictness information
678 * inline pragma (though that is bit more debatable)
681 Mostly this is just an optimisation, but it's *vital* to
682 transfer the occurrence info. Consider
684 NonRec { f = /\a. let Rec { g* = ..g.. } in ... }
686 where the '*' means 'LoopBreaker'. Then if we float we must get
688 Rec { g'* = /\a. ...(g' a)... }
689 NonRec { f = /\a. ...[g' a/g]....}
691 where g' is also marked as LoopBreaker. If not, terrible things
692 can happen if we re-simplify the binding (and the Simplifier does
693 sometimes simplify a term twice); see Trac #4345.
695 It's not so simple to retain
698 so we simply discard those. Sooner or later this may bite us.
700 If we abstract wrt one or more *value* binders, we must modify the
701 arity and strictness info before transferring it. E.g.
705 + substitute (g' y) for g
706 Notice that g' has an arity one more than the original g
709 transferPolyIdInfo :: Id -- Original Id
710 -> [Var] -- Abstract wrt these variables
713 transferPolyIdInfo old_id abstract_wrt new_id
714 = modifyIdInfo transfer new_id
716 arity_increase = count isId abstract_wrt -- Arity increases by the
717 -- number of value binders
719 old_info = idInfo old_id
720 old_arity = arityInfo old_info
721 old_inline_prag = inlinePragInfo old_info
722 old_occ_info = occInfo old_info
723 new_arity = old_arity + arity_increase
724 old_strictness = strictnessInfo old_info
725 new_strictness = fmap (increaseStrictSigArity arity_increase) old_strictness
727 transfer new_info = new_info `setStrictnessInfo` new_strictness
728 `setArityInfo` new_arity
729 `setInlinePragInfo` old_inline_prag
730 `setOccInfo` old_occ_info