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,
31 mkSysLocal, mkSysLocalM, mkUserLocal, mkUserLocalM,
32 mkTemplateLocals, mkTemplateLocalsNum, mkTemplateLocal,
33 mkWorkerId, mkExportedLocalId,
35 -- ** Taking an Id apart
36 idName, idType, idUnique, idInfo,
37 isId, globalIdDetails, idPrimRep,
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,
53 isPrimOpId, isPrimOpId_maybe,
54 isFCallId, isFCallId_maybe,
55 isDataConWorkId, isDataConWorkId_maybe, isDataConId_maybe, idDataCon,
56 isBottomingId, idIsFrom,
57 isTickBoxOp, isTickBoxOp_maybe,
60 -- ** Inline pragma stuff
61 idInlinePragma, setInlinePragma, modifyInlinePragma,
63 -- ** One-shot lambdas
64 isOneShotBndr, isOneShotLambda, isStateHackType,
65 setOneShotLambda, clearOneShotLambda,
67 -- ** Reading 'IdInfo' fields
69 idNewDemandInfo, idNewDemandInfo_maybe,
70 idNewStrictness, idNewStrictness_maybe,
73 idSpecialisation, idCoreRules, idHasRules,
84 -- ** Writing 'IdInfo' fields
88 setIdNewStrictness, zapIdNewStrictness,
92 setIdOccInfo, zapIdOccInfo,
101 #include "HsVersions.h"
103 import CoreSyn ( CoreRule, Unfolding )
113 #ifdef OLD_STRICTNESS
114 import qualified Demand
132 -- infixl so you can say (id `set` a `set` b)
133 infixl 1 `setIdUnfolding`,
135 `setIdNewDemandInfo`,
136 `setIdNewStrictness`,
138 `setIdSpecialisation`,
141 #ifdef OLD_STRICTNESS
148 %************************************************************************
150 \subsection{Basic Id manipulation}
152 %************************************************************************
158 idUnique :: Id -> Unique
164 idInfo :: Id -> IdInfo
167 idPrimRep :: Id -> PrimRep
168 idPrimRep id = typePrimRep (idType id)
170 globalIdDetails :: Id -> GlobalIdDetails
171 globalIdDetails = globalIdVarDetails
174 setIdName :: Id -> Name -> Id
175 setIdName = setVarName
177 setIdUnique :: Id -> Unique -> Id
178 setIdUnique = setVarUnique
180 -- | Not only does this set the 'Id' 'Type', it also evaluates the type to try and
181 -- reduce space usage
182 setIdType :: Id -> Type -> Id
183 setIdType id ty = seqType ty `seq` Var.setVarType id ty
185 setIdExported :: Id -> Id
186 setIdExported = setIdVarExported
188 setIdNotExported :: Id -> Id
189 setIdNotExported = setIdVarNotExported
191 localiseId :: Id -> Id
192 -- Make an with the same unique and type as the
193 -- incoming Id, but with an *Internal* Name and *LocalId* flavour
195 | isLocalId id && isInternalName name
198 = mkLocalIdWithInfo (localiseName name) (idType id) (idInfo id)
202 globaliseId :: GlobalIdDetails -> Id -> Id
203 globaliseId = globaliseIdVar
205 lazySetIdInfo :: Id -> IdInfo -> Id
206 lazySetIdInfo = lazySetVarIdInfo
208 setIdInfo :: Id -> IdInfo -> Id
209 setIdInfo id info = seqIdInfo info `seq` (lazySetIdInfo id info)
210 -- Try to avoid spack leaks by seq'ing
212 modifyIdInfo :: (IdInfo -> IdInfo) -> Id -> Id
213 modifyIdInfo fn id = setIdInfo id (fn (idInfo id))
215 -- maybeModifyIdInfo tries to avoid unnecesary thrashing
216 maybeModifyIdInfo :: Maybe IdInfo -> Id -> Id
217 maybeModifyIdInfo (Just new_info) id = lazySetIdInfo id new_info
218 maybeModifyIdInfo Nothing id = id
221 %************************************************************************
223 \subsection{Simple Id construction}
225 %************************************************************************
227 Absolutely all Ids are made by mkId. It is just like Var.mkId,
228 but in addition it pins free-tyvar-info onto the Id's type,
229 where it can easily be found.
231 Note [Free type variables]
232 ~~~~~~~~~~~~~~~~~~~~~~~~~~
233 At one time we cached the free type variables of the type of an Id
234 at the root of the type in a TyNote. The idea was to avoid repeating
235 the free-type-variable calculation. But it turned out to slow down
236 the compiler overall. I don't quite know why; perhaps finding free
237 type variables of an Id isn't all that common whereas applying a
238 substitution (which changes the free type variables) is more common.
239 Anyway, we removed it in March 2008.
242 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
243 mkGlobalId :: GlobalIdDetails -> Name -> Type -> IdInfo -> Id
244 mkGlobalId = mkGlobalIdVar
246 -- | Make a global 'Id' without any extra information at all
247 mkVanillaGlobal :: Name -> Type -> Id
248 mkVanillaGlobal name ty = mkVanillaGlobalWithInfo name ty vanillaIdInfo
250 -- | Make a global 'Id' with no global information but some generic 'IdInfo'
251 mkVanillaGlobalWithInfo :: Name -> Type -> IdInfo -> Id
252 mkVanillaGlobalWithInfo = mkGlobalId VanillaGlobal
255 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
256 mkLocalId :: Name -> Type -> Id
257 mkLocalId name ty = mkLocalIdWithInfo name ty vanillaIdInfo
259 mkLocalIdWithInfo :: Name -> Type -> IdInfo -> Id
260 mkLocalIdWithInfo = mkLocalIdVar
261 -- Note [Free type variables]
263 -- | Create a local 'Id' that is marked as exported. This prevents things attached to it from being removed as dead code.
264 mkExportedLocalId :: Name -> Type -> Id
265 mkExportedLocalId name ty = mkExportedLocalIdVar name ty vanillaIdInfo
266 -- Note [Free type variables]
269 -- | Create a system local 'Id'. These are local 'Id's (see "Var#globalvslocal") that are created by the compiler out of thin air
270 mkSysLocal :: FastString -> Unique -> Type -> Id
271 mkSysLocal fs uniq ty = mkLocalId (mkSystemVarName uniq fs) ty
273 mkSysLocalM :: MonadUnique m => FastString -> Type -> m Id
274 mkSysLocalM fs ty = getUniqueM >>= (\uniq -> return (mkSysLocal fs uniq ty))
277 -- | Create a user local 'Id'. These are local 'Id's (see "Var#globalvslocal") with a name and location that the user might recognize
278 mkUserLocal :: OccName -> Unique -> Type -> SrcSpan -> Id
279 mkUserLocal occ uniq ty loc = mkLocalId (mkInternalName uniq occ loc) ty
281 mkUserLocalM :: MonadUnique m => OccName -> Type -> SrcSpan -> m Id
282 mkUserLocalM occ ty loc = getUniqueM >>= (\uniq -> return (mkUserLocal occ uniq ty loc))
286 Make some local @Ids@ for a template @CoreExpr@. These have bogus
287 @Uniques@, but that's OK because the templates are supposed to be
288 instantiated before use.
291 -- | Workers get local names. "CoreTidy" will externalise these if necessary
292 mkWorkerId :: Unique -> Id -> Type -> Id
293 mkWorkerId uniq unwrkr ty
294 = mkLocalId wkr_name ty
296 wkr_name = mkInternalName uniq (mkWorkerOcc (getOccName unwrkr)) (getSrcSpan unwrkr)
298 -- | Create a /template local/: a family of system local 'Id's in bijection with @Int@s, typically used in unfoldings
299 mkTemplateLocal :: Int -> Type -> Id
300 mkTemplateLocal i ty = mkSysLocal (fsLit "tpl") (mkBuiltinUnique i) ty
302 -- | Create a template local for a series of types
303 mkTemplateLocals :: [Type] -> [Id]
304 mkTemplateLocals = mkTemplateLocalsNum 1
306 -- | Create a template local for a series of type, but start from a specified template local
307 mkTemplateLocalsNum :: Int -> [Type] -> [Id]
308 mkTemplateLocalsNum n tys = zipWith mkTemplateLocal [n..] tys
312 %************************************************************************
314 \subsection{Basic predicates on @Id@s}
316 %************************************************************************
322 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
323 isLocalId :: Id -> Bool
324 isLocalId = isLocalIdVar
326 -- | For an explanation of global vs. local 'Id's, see "Var#globalvslocal"
327 isGlobalId :: Id -> Bool
328 isGlobalId = isGlobalIdVar
330 -- | Determines whether an 'Id' is marked as exported and hence will not be considered dead code
331 isExportedId :: Id -> Bool
332 isExportedId = isExportedIdVar
335 %************************************************************************
337 \subsection{Special Ids}
339 %************************************************************************
342 -- | If the 'Id' is that for a record selector, extract the 'sel_tycon' and label. Panic otherwise
343 recordSelectorFieldLabel :: Id -> (TyCon, FieldLabel)
344 recordSelectorFieldLabel id
345 = case globalIdDetails id of
346 RecordSelId { sel_tycon = tycon, sel_label = lbl } -> (tycon,lbl)
347 _ -> panic "recordSelectorFieldLabel"
349 isRecordSelector :: Id -> Bool
350 isNaughtyRecordSelector :: Id -> Bool
351 isPrimOpId :: Id -> Bool
352 isFCallId :: Id -> Bool
353 isDataConWorkId :: Id -> Bool
355 isClassOpId_maybe :: Id -> Maybe Class
356 isPrimOpId_maybe :: Id -> Maybe PrimOp
357 isFCallId_maybe :: Id -> Maybe ForeignCall
358 isDataConWorkId_maybe :: Id -> Maybe DataCon
360 isRecordSelector id = case globalIdDetails id of
361 RecordSelId {} -> True
364 isNaughtyRecordSelector id = case globalIdDetails id of
365 RecordSelId { sel_naughty = n } -> n
368 isClassOpId_maybe id = case globalIdDetails id of
369 ClassOpId cls -> Just cls
372 isPrimOpId id = case globalIdDetails id of
376 isPrimOpId_maybe id = case globalIdDetails id of
377 PrimOpId op -> Just op
380 isFCallId id = case globalIdDetails id of
384 isFCallId_maybe id = case globalIdDetails id of
385 FCallId call -> Just call
388 isDataConWorkId id = case globalIdDetails id of
389 DataConWorkId _ -> True
392 isDataConWorkId_maybe id = case globalIdDetails id of
393 DataConWorkId con -> Just con
396 isDataConId_maybe :: Id -> Maybe DataCon
397 isDataConId_maybe id = case globalIdDetails id of
398 DataConWorkId con -> Just con
399 DataConWrapId con -> Just con
402 idDataCon :: Id -> DataCon
403 -- ^ Get from either the worker or the wrapper 'Id' to the 'DataCon'. Currently used only in the desugarer.
405 -- INVARIANT: @idDataCon (dataConWrapId d) = d@: remember, 'dataConWrapId' can return either the wrapper or the worker
406 idDataCon id = isDataConId_maybe id `orElse` pprPanic "idDataCon" (ppr id)
409 isDictId :: Id -> Bool
410 isDictId id = isDictTy (idType id)
412 hasNoBinding :: Id -> Bool
413 -- ^ Returns @True@ of an 'Id' which may not have a
414 -- binding, even though it is defined in this module.
416 -- Data constructor workers used to be things of this kind, but
417 -- they aren't any more. Instead, we inject a binding for
418 -- them at the CorePrep stage.
419 -- EXCEPT: unboxed tuples, which definitely have no binding
420 hasNoBinding id = case globalIdDetails id of
421 PrimOpId _ -> True -- See Note [Primop wrappers]
423 DataConWorkId dc -> isUnboxedTupleCon dc
426 isImplicitId :: Id -> Bool
427 -- ^ 'isImplicitId' tells whether an 'Id's info is implied by other
428 -- declarations, so we don't need to put its signature in an interface
429 -- file, even if it's mentioned in some other interface unfolding.
431 = case globalIdDetails id of
432 RecordSelId {} -> True
436 DataConWorkId _ -> True
437 DataConWrapId _ -> True
438 -- These are are implied by their type or class decl;
439 -- remember that all type and class decls appear in the interface file.
440 -- The dfun id is not an implicit Id; it must *not* be omitted, because
441 -- it carries version info for the instance decl
444 idIsFrom :: Module -> Id -> Bool
445 idIsFrom mod id = nameIsLocalOrFrom mod (idName id)
448 Note [Primop wrappers]
449 ~~~~~~~~~~~~~~~~~~~~~~
450 Currently hasNoBinding claims that PrimOpIds don't have a curried
451 function definition. But actually they do, in GHC.PrimopWrappers,
452 which is auto-generated from prelude/primops.txt.pp. So actually, hasNoBinding
453 could return 'False' for PrimOpIds.
455 But we'd need to add something in CoreToStg to swizzle any unsaturated
456 applications of GHC.Prim.plusInt# to GHC.PrimopWrappers.plusInt#.
458 Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's
459 used by GHCi, which does not implement primops direct at all.
464 isDeadBinder :: Id -> Bool
465 isDeadBinder bndr | isId bndr = isDeadOcc (idOccInfo bndr)
466 | otherwise = False -- TyVars count as not dead
470 isTickBoxOp :: Id -> Bool
472 case globalIdDetails id of
473 TickBoxOpId _ -> True
476 isTickBoxOp_maybe :: Id -> Maybe TickBoxOp
477 isTickBoxOp_maybe id =
478 case globalIdDetails id of
479 TickBoxOpId tick -> Just tick
483 %************************************************************************
485 \subsection{IdInfo stuff}
487 %************************************************************************
490 ---------------------------------
492 idArity :: Id -> Arity
493 idArity id = arityInfo (idInfo id)
495 setIdArity :: Id -> Arity -> Id
496 setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
498 #ifdef OLD_STRICTNESS
499 ---------------------------------
501 idStrictness :: Id -> StrictnessInfo
502 idStrictness id = strictnessInfo (idInfo id)
504 setIdStrictness :: Id -> StrictnessInfo -> Id
505 setIdStrictness id strict_info = modifyIdInfo (`setStrictnessInfo` strict_info) id
508 -- | Returns true if an application to n args would diverge
509 isBottomingId :: Id -> Bool
510 isBottomingId id = isBottomingSig (idNewStrictness id)
512 idNewStrictness_maybe :: Id -> Maybe StrictSig
513 idNewStrictness :: Id -> StrictSig
515 idNewStrictness_maybe id = newStrictnessInfo (idInfo id)
516 idNewStrictness id = idNewStrictness_maybe id `orElse` topSig
518 setIdNewStrictness :: Id -> StrictSig -> Id
519 setIdNewStrictness id sig = modifyIdInfo (`setNewStrictnessInfo` Just sig) id
521 zapIdNewStrictness :: Id -> Id
522 zapIdNewStrictness id = modifyIdInfo (`setNewStrictnessInfo` Nothing) id
524 -- | This predicate says whether the 'Id' has a strict demand placed on it or
525 -- has a type such that it can always be evaluated strictly (e.g., an
526 -- unlifted type, but see the comment for 'isStrictType'). We need to
527 -- check separately whether the 'Id' has a so-called \"strict type\" because if
528 -- the demand for the given @id@ hasn't been computed yet but @id@ has a strict
529 -- type, we still want @isStrictId id@ to be @True@.
530 isStrictId :: Id -> Bool
532 = ASSERT2( isId id, text "isStrictId: not an id: " <+> ppr id )
533 (isStrictDmd (idNewDemandInfo id)) ||
534 (isStrictType (idType id))
536 ---------------------------------
538 idWorkerInfo :: Id -> WorkerInfo
539 idWorkerInfo id = workerInfo (idInfo id)
541 setIdWorkerInfo :: Id -> WorkerInfo -> Id
542 setIdWorkerInfo id work_info = modifyIdInfo (`setWorkerInfo` work_info) id
544 ---------------------------------
546 idUnfolding :: Id -> Unfolding
547 idUnfolding id = unfoldingInfo (idInfo id)
549 setIdUnfolding :: Id -> Unfolding -> Id
550 setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
552 #ifdef OLD_STRICTNESS
553 ---------------------------------
555 idDemandInfo :: Id -> Demand.Demand
556 idDemandInfo id = demandInfo (idInfo id)
558 setIdDemandInfo :: Id -> Demand.Demand -> Id
559 setIdDemandInfo id demand_info = modifyIdInfo (`setDemandInfo` demand_info) id
562 idNewDemandInfo_maybe :: Id -> Maybe NewDemand.Demand
563 idNewDemandInfo :: Id -> NewDemand.Demand
565 idNewDemandInfo_maybe id = newDemandInfo (idInfo id)
566 idNewDemandInfo id = newDemandInfo (idInfo id) `orElse` NewDemand.topDmd
568 setIdNewDemandInfo :: Id -> NewDemand.Demand -> Id
569 setIdNewDemandInfo id dmd = modifyIdInfo (`setNewDemandInfo` Just dmd) id
571 ---------------------------------
573 idSpecialisation :: Id -> SpecInfo
574 idSpecialisation id = specInfo (idInfo id)
576 idCoreRules :: Id -> [CoreRule]
577 idCoreRules id = specInfoRules (idSpecialisation id)
579 idHasRules :: Id -> Bool
580 idHasRules id = not (isEmptySpecInfo (idSpecialisation id))
582 setIdSpecialisation :: Id -> SpecInfo -> Id
583 setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
585 ---------------------------------
587 idCafInfo :: Id -> CafInfo
588 #ifdef OLD_STRICTNESS
589 idCafInfo id = case cgInfo (idInfo id) of
590 NoCgInfo -> pprPanic "idCafInfo" (ppr id)
591 info -> cgCafInfo info
593 idCafInfo id = cafInfo (idInfo id)
596 setIdCafInfo :: Id -> CafInfo -> Id
597 setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
599 ---------------------------------
601 #ifdef OLD_STRICTNESS
602 idCprInfo :: Id -> CprInfo
603 idCprInfo id = cprInfo (idInfo id)
605 setIdCprInfo :: Id -> CprInfo -> Id
606 setIdCprInfo id cpr_info = modifyIdInfo (`setCprInfo` cpr_info) id
609 ---------------------------------
611 idOccInfo :: Id -> OccInfo
612 idOccInfo id = occInfo (idInfo id)
614 setIdOccInfo :: Id -> OccInfo -> Id
615 setIdOccInfo id occ_info = modifyIdInfo (`setOccInfo` occ_info) id
617 zapIdOccInfo :: Id -> Id
618 zapIdOccInfo b = b `setIdOccInfo` NoOccInfo
622 ---------------------------------
624 The inline pragma tells us to be very keen to inline this Id, but it's still
625 OK not to if optimisation is switched off.
628 idInlinePragma :: Id -> InlinePragInfo
629 idInlinePragma id = inlinePragInfo (idInfo id)
631 setInlinePragma :: Id -> InlinePragInfo -> Id
632 setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
634 modifyInlinePragma :: Id -> (InlinePragInfo -> InlinePragInfo) -> Id
635 modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
639 ---------------------------------
642 idLBVarInfo :: Id -> LBVarInfo
643 idLBVarInfo id = lbvarInfo (idInfo id)
645 -- | Returns whether the lambda associated with the 'Id' is certainly applied at most once
646 -- OR we are applying the \"state hack\" which makes it appear as if theis is the case for
647 -- lambdas used in @IO@. You should prefer using this over 'isOneShotLambda'
648 isOneShotBndr :: Id -> Bool
649 -- This one is the "business end", called externally.
650 -- Its main purpose is to encapsulate the Horrible State Hack
651 isOneShotBndr id = isOneShotLambda id || isStateHackType (idType id)
653 -- | Should we apply the state hack to values of this 'Type'?
654 isStateHackType :: Type -> Bool
659 = case splitTyConApp_maybe ty of
660 Just (tycon,_) -> tycon == statePrimTyCon
662 -- This is a gross hack. It claims that
663 -- every function over realWorldStatePrimTy is a one-shot
664 -- function. This is pretty true in practice, and makes a big
665 -- difference. For example, consider
666 -- a `thenST` \ r -> ...E...
667 -- The early full laziness pass, if it doesn't know that r is one-shot
668 -- will pull out E (let's say it doesn't mention r) to give
669 -- let lvl = E in a `thenST` \ r -> ...lvl...
670 -- When `thenST` gets inlined, we end up with
671 -- let lvl = E in \s -> case a s of (r, s') -> ...lvl...
672 -- and we don't re-inline E.
674 -- It would be better to spot that r was one-shot to start with, but
675 -- I don't want to rely on that.
677 -- Another good example is in fill_in in PrelPack.lhs. We should be able to
678 -- spot that fill_in has arity 2 (and when Keith is done, we will) but we can't yet.
681 -- | Returns whether the lambda associated with the 'Id' is certainly applied at most once.
682 -- You probably want to use 'isOneShotBndr' instead
683 isOneShotLambda :: Id -> Bool
684 isOneShotLambda id = case idLBVarInfo id of
685 IsOneShotLambda -> True
688 setOneShotLambda :: Id -> Id
689 setOneShotLambda id = modifyIdInfo (`setLBVarInfo` IsOneShotLambda) id
691 clearOneShotLambda :: Id -> Id
692 clearOneShotLambda id
693 | isOneShotLambda id = modifyIdInfo (`setLBVarInfo` NoLBVarInfo) id
696 -- The OneShotLambda functions simply fiddle with the IdInfo flag
697 -- But watch out: this may change the type of something else
699 -- If we change the one-shot-ness of x, f's type changes
703 zapInfo :: (IdInfo -> Maybe IdInfo) -> Id -> Id
704 zapInfo zapper id = maybeModifyIdInfo (zapper (idInfo id)) id
706 zapLamIdInfo :: Id -> Id
707 zapLamIdInfo = zapInfo zapLamInfo
709 zapDemandIdInfo :: Id -> Id
710 zapDemandIdInfo = zapInfo zapDemandInfo
712 zapFragileIdInfo :: Id -> Id
713 zapFragileIdInfo = zapInfo zapFragileInfo
716 Note [transferPolyIdInfo]
717 ~~~~~~~~~~~~~~~~~~~~~~~~~
720 f = /\a. let g = rhs in ...
722 where g has interesting strictness information. Then if we float thus
727 we *do not* want to lose the strictness information on g. Nor arity.
729 It's simple to retain strictness and arity, but not so simple to retain
732 so we simply discard those. Sooner or later this may bite us.
734 This transfer is used in two places:
735 FloatOut (long-distance let-floating)
736 SimplUtils.abstractFloats (short-distance let-floating)
739 transferPolyIdInfo :: Id -> Id -> Id
740 transferPolyIdInfo old_id new_id
741 = modifyIdInfo transfer new_id
743 old_info = idInfo old_id
744 transfer new_info = new_info `setNewStrictnessInfo` (newStrictnessInfo old_info)
745 `setArityInfo` (arityInfo old_info)