+
+\end{code}
+
+%************************************************************************
+%* *
+\subsection{Thin air entities}
+%* *
+%************************************************************************
+
+These are Ids that we need to reference in various parts of the
+system, and we'd like to pull them out of thin air rather than pass
+them around. We'd also like to have all the IdInfo available for each
+one: i.e. everything that gets pulled out of the interface file.
+
+The solution is to generate this map of global Ids after the
+typechecker, and assign it to a global variable. Any subsequent
+pass may refer to the map to pull Ids out. Any invalid
+(i.e. pre-typechecker) access to the map will result in a panic.
+
+\begin{code}
+thinAirIdNames
+ = map mkKnownKeyGlobal
+ [
+ -- Needed for converting literals to Integers (used in tidyCoreExpr)
+ (varQual (pREL_BASE, SLIT("int2Integer")), int2IntegerIdKey)
+ , (varQual (pREL_BASE, SLIT("addr2Integer")), addr2IntegerIdKey)
+
+ -- OK, this is Will's idea: we should have magic values for Integers 0,
+ -- +1, +2, and -1 (go ahead, fire me):
+ , (varQual (pREL_BASE, SLIT("integer_0")), integerZeroIdKey)
+ , (varQual (pREL_BASE, SLIT("integer_1")), integerPlusOneIdKey)
+ , (varQual (pREL_BASE, SLIT("integer_2")), integerPlusTwoIdKey)
+ , (varQual (pREL_BASE, SLIT("integer_m1")), integerMinusOneIdKey)
+
+
+ -- String literals
+ , (varQual (pREL_PACK, SLIT("packCString#")), packCStringIdKey)
+ , (varQual (pREL_PACK, SLIT("unpackCString#")), unpackCStringIdKey)
+ , (varQual (pREL_PACK, SLIT("unpackNBytes#")), unpackCString2IdKey)
+ , (varQual (pREL_PACK, SLIT("unpackAppendCString#")), unpackCStringAppendIdKey)
+ , (varQual (pREL_PACK, SLIT("unpackFoldrCString#")), unpackCStringFoldrIdKey)
+
+ -- Folds; introduced by desugaring list comprehensions
+ , (varQual (pREL_BASE, SLIT("foldr")), foldrIdKey)
+ ]
+
+thinAirModules = [pREL_PACK] -- See notes with RnIfaces.findAndReadIface
+
+noRepIntegerIds = [integerZeroId, integerPlusOneId, integerPlusTwoId, integerMinusOneId,
+ int2IntegerId, addr2IntegerId]
+
+noRepStrIds = [unpackCString2Id, unpackCStringId]
+
+int2IntegerId = lookupThinAirId int2IntegerIdKey
+addr2IntegerId = lookupThinAirId addr2IntegerIdKey
+
+integerMinusOneId = lookupThinAirId integerMinusOneIdKey
+integerZeroId = lookupThinAirId integerZeroIdKey
+integerPlusOneId = lookupThinAirId integerPlusOneIdKey
+integerPlusTwoId = lookupThinAirId integerPlusTwoIdKey
+
+packStringForCId = lookupThinAirId packCStringIdKey
+unpackCStringId = lookupThinAirId unpackCStringIdKey
+unpackCString2Id = lookupThinAirId unpackCString2IdKey
+unpackCStringAppendId = lookupThinAirId unpackCStringAppendIdKey
+unpackCStringFoldrId = lookupThinAirId unpackCStringFoldrIdKey
+
+foldrId = lookupThinAirId foldrIdKey
+\end{code}
+
+
+\begin{code}
+\end{code}
+
+\begin{code}
+thinAirIdMapRef :: IORef (UniqFM Id)
+thinAirIdMapRef = unsafePerformIO (newIORef (panic "thinAirIdMap: still empty"))
+
+setThinAirIds :: [Id] -> IO ()
+setThinAirIds thin_air_ids
+ = writeIORef thinAirIdMapRef the_map
+ where
+ the_map = listToUFM [(varUnique id, id) | id <- thin_air_ids]
+
+thinAirIdMap :: UniqFM Id
+thinAirIdMap = unsafePerformIO (readIORef thinAirIdMapRef)
+ -- Read it just once, the first time someone tugs on thinAirIdMap
+
+lookupThinAirId :: Unique -> Id
+lookupThinAirId uniq = lookupWithDefaultUFM thinAirIdMap
+ (panic "lookupThinAirId: no mapping") uniq