2 % (c) The GRASP Project, Glasgow University, 1994-1998
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
6 This module is about types that can be defined in Haskell, but which
7 must be wired into the compiler nonetheless.
9 This module tracks the ``state interface'' document, ``GHC prelude:
10 types and operations.''
27 falseDataCon, falseDataConId,
52 unitTyCon, unitDataConId, pairTyCon,
53 unboxedSingletonTyCon, unboxedSingletonDataCon,
54 unboxedPairTyCon, unboxedPairDataCon,
58 trueDataCon, trueDataConId,
65 isFFIArgumentTy, -- :: Bool -> Type -> Bool
66 isFFIResultTy, -- :: Type -> Bool
67 isFFIExternalTy, -- :: Type -> Bool
68 isFFIDynResultTy, -- :: Type -> Bool
69 isFFILabelTy, -- :: Type -> Bool
70 isAddrTy, -- :: Type -> Bool
71 isForeignObjTy -- :: Type -> Bool
75 #include "HsVersions.h"
77 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
84 import Constants ( mAX_TUPLE_SIZE )
85 import Module ( Module, mkPrelModule )
86 import Name ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, mkWorkerOcc, dataName )
87 import DataCon ( DataCon, StrictnessMark(..), mkDataCon, dataConId )
88 import Var ( TyVar, tyVarKind )
89 import TyCon ( TyCon, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
90 mkAlgTyCon, mkSynTyCon, mkTupleTyCon, isUnLiftedTyCon
92 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
93 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
94 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
96 splitTyConApp_maybe, repType,
97 TauType, ClassContext )
99 import CmdLineOpts ( opt_GlasgowExts )
102 alpha_tyvar = [alphaTyVar]
104 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
106 pcRecDataTyCon, pcNonRecDataTyCon
107 :: Unique{-TyConKey-} -> Module -> FAST_STRING
108 -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
110 pcRecDataTyCon = pcTyCon DataTyCon Recursive
111 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
113 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
116 tycon = mkAlgTyCon name kind
126 name = mkWiredInTyConName key mod str tycon
127 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
129 pcSynTyCon key mod str kind arity tyvars expansion argvrcs -- this fun never used!
132 tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
133 name = mkWiredInTyConName key mod str tycon
135 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
136 -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
137 -- The unique is the first of two free uniques;
138 -- the first is used for the datacon itself and the worker;
139 -- the second is used for the wrapper.
140 pcDataCon wrap_key mod str tyvars context arg_tys tycon
143 data_con = mkDataCon wrap_name
144 [ NotMarkedStrict | a <- arg_tys ]
145 [ {- no labelled fields -} ]
146 tyvars context [] [] arg_tys tycon work_id wrap_id
148 work_occ = mkWorkerOcc wrap_occ
149 work_key = incrUnique wrap_key
150 work_name = mkWiredInIdName work_key mod work_occ work_id
151 work_id = mkDataConId work_name data_con
153 wrap_occ = mkSrcOccFS dataName str
154 wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
155 wrap_id = mkDataConWrapId data_con
159 %************************************************************************
161 \subsection[TysWiredIn-tuples]{The tuple types}
163 %************************************************************************
166 tupleTyCon :: Boxity -> Arity -> TyCon
167 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
168 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
169 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
171 tupleCon :: Boxity -> Arity -> DataCon
172 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
173 tupleCon Boxed i = snd (boxedTupleArr ! i)
174 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
176 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
177 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
178 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
180 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
181 mk_tuple boxity arity = (tycon, tuple_con)
183 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity
184 tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
185 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
186 res_kind | isBoxed boxity = boxedTypeKind
187 | otherwise = unboxedTypeKind
189 tyvars | isBoxed boxity = take arity alphaTyVars
190 | otherwise = take arity openAlphaTyVars
192 tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
193 tyvar_tys = mkTyVarTys tyvars
194 (mod_name, name_str) = mkTupNameStr boxity arity
195 tc_uniq = mkTupleTyConUnique boxity arity
196 dc_uniq = mkTupleDataConUnique boxity arity
197 mod = mkPrelModule mod_name
199 unitTyCon = tupleTyCon Boxed 0
200 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
202 pairTyCon = tupleTyCon Boxed 2
204 unboxedSingletonTyCon = tupleTyCon Unboxed 1
205 unboxedSingletonDataCon = tupleCon Unboxed 1
207 unboxedPairTyCon = tupleTyCon Unboxed 2
208 unboxedPairDataCon = tupleCon Unboxed 2
211 %************************************************************************
213 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
215 %************************************************************************
218 -- The Void type is represented as a data type with no constructors
219 -- It's a built in type (i.e. there's no way to define it in Haskell;
220 -- the nearest would be
222 -- data Void = -- No constructors!
224 -- ) It's boxed; there is only one value of this
225 -- type, namely "void", whose semantics is just bottom.
227 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
234 charTy = mkTyConTy charTyCon
236 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [] [charDataCon]
237 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
239 stringTy = mkListTy charTy -- convenience only
243 intTy = mkTyConTy intTyCon
245 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
246 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
248 isIntTy :: Type -> Bool
249 isIntTy = isTyCon intTyConKey
254 wordTy = mkTyConTy wordTyCon
256 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [] [wordDataCon]
257 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
261 addrTy = mkTyConTy addrTyCon
263 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
264 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
266 isAddrTy :: Type -> Bool
267 isAddrTy = isTyCon addrTyConKey
271 floatTy = mkTyConTy floatTyCon
273 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
274 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
276 isFloatTy :: Type -> Bool
277 isFloatTy = isTyCon floatTyConKey
281 doubleTy = mkTyConTy doubleTyCon
283 isDoubleTy :: Type -> Bool
284 isDoubleTy = isTyCon doubleTyConKey
286 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
287 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
292 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
293 alpha_tyvar [(True,False)] [stablePtrDataCon]
296 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
297 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
302 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
303 [] [] [foreignObjDataCon]
306 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
307 [] [] [foreignObjPrimTy] foreignObjTyCon
309 isForeignObjTy :: Type -> Bool
310 isForeignObjTy = isTyCon foreignObjTyConKey
313 %************************************************************************
315 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
317 %************************************************************************
319 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
322 integerTy = mkTyConTy integerTyCon
324 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
325 [] [] [smallIntegerDataCon, largeIntegerDataCon]
327 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
328 [] [] [intPrimTy] integerTyCon
329 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
330 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
333 isIntegerTy :: Type -> Bool
334 isIntegerTy = isTyCon integerTyConKey
338 %************************************************************************
340 \subsection[TysWiredIn-ext-type]{External types}
342 %************************************************************************
344 The compiler's foreign function interface supports the passing of a
345 restricted set of types as arguments and results (the restricting factor
349 isFFIArgumentTy :: Bool -> Type -> Bool
350 -- Checks for valid argument type for a 'foreign import'
351 isFFIArgumentTy is_safe ty = checkRepTyCon (legalOutgoingTyCon is_safe) ty
353 isFFIExternalTy :: Type -> Bool
354 -- Types that are allowed as arguments of a 'foreign export'
355 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
357 isFFIResultTy :: Type -> Bool
358 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
359 -- Maybe we should distinguish between import and export, but
360 -- here we just choose the more restrictive 'incoming' predicate
361 -- But we allow () as well
362 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
364 -- The result type of a foreign export dynamic must be either Addr, or
365 -- a newtype of Addr.
366 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
368 -- The type of a foreign label must be either Addr, or
369 -- a newtype of Addr.
370 isFFILabelTy = checkRepTyCon (== addrTyCon)
372 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
373 -- look through newtypes
374 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
376 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
377 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
378 Just (tycon, _) -> check_tc tycon
381 isTyCon :: Unique -> Type -> Bool
382 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
385 ----------------------------------------------
386 These chaps do the work; they are not exported
387 ----------------------------------------------
390 legalIncomingTyCon :: TyCon -> Bool
391 -- It's illegal to return foreign objects and (mutable)
392 -- bytearrays from a _ccall_ / foreign declaration
393 -- (or be passed them as arguments in foreign exported functions).
394 legalIncomingTyCon tc
395 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
397 -- It's also illegal to make foreign exports that take unboxed
398 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
400 = boxedMarshalableTyCon tc
402 legalOutgoingTyCon :: Bool -> TyCon -> Bool
403 -- Checks validity of types going from Haskell -> external world
404 -- The boolean is true for a 'safe' call (when we don't want to
405 -- pass Haskell pointers to the world)
406 legalOutgoingTyCon be_safe tc
407 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
410 = marshalableTyCon tc
413 = (opt_GlasgowExts && isUnLiftedTyCon tc)
414 || boxedMarshalableTyCon tc
416 boxedMarshalableTyCon tc
417 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
418 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
419 , floatTyConKey, doubleTyConKey
420 , addrTyConKey, charTyConKey, foreignObjTyConKey
422 , byteArrayTyConKey, mutableByteArrayTyConKey
428 %************************************************************************
430 \subsection[TysWiredIn-Bool]{The @Bool@ type}
432 %************************************************************************
434 An ordinary enumeration type, but deeply wired in. There are no
435 magical operations on @Bool@ (just the regular Prelude code).
437 {\em BEGIN IDLE SPECULATION BY SIMON}
439 This is not the only way to encode @Bool@. A more obvious coding makes
440 @Bool@ just a boxed up version of @Bool#@, like this:
443 data Bool = MkBool Bool#
446 Unfortunately, this doesn't correspond to what the Report says @Bool@
447 looks like! Furthermore, we get slightly less efficient code (I
448 think) with this coding. @gtInt@ would look like this:
451 gtInt :: Int -> Int -> Bool
452 gtInt x y = case x of I# x# ->
454 case (gtIntPrim x# y#) of
458 Notice that the result of the @gtIntPrim@ comparison has to be turned
459 into an integer (here called @b#@), and returned in a @MkBool@ box.
461 The @if@ expression would compile to this:
464 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
467 I think this code is a little less efficient than the previous code,
468 but I'm not certain. At all events, corresponding with the Report is
469 important. The interesting thing is that the language is expressive
470 enough to describe more than one alternative; and that a type doesn't
471 necessarily need to be a straightforwardly boxed version of its
472 primitive counterpart.
474 {\em END IDLE SPECULATION BY SIMON}
477 boolTy = mkTyConTy boolTyCon
479 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey
480 pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
482 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
483 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
485 falseDataConId = dataConId falseDataCon
486 trueDataConId = dataConId trueDataCon
489 %************************************************************************
491 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
493 %************************************************************************
495 Special syntax, deeply wired in, but otherwise an ordinary algebraic
498 data [] a = [] | a : (List a)
500 data (,) a b = (,,) a b
505 mkListTy :: Type -> Type
506 mkListTy ty = mkTyConApp listTyCon [ty]
508 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
510 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
511 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
513 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
514 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
515 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
516 -- Interesting: polymorphic recursion would help here.
517 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
518 -- gets the over-specific type (Type -> Type)
521 %************************************************************************
523 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
525 %************************************************************************
527 The tuple types are definitely magic, because they form an infinite
532 They have a special family of type constructors, of type @TyCon@
533 These contain the tycon arity, but don't require a Unique.
536 They have a special family of constructors, of type
537 @Id@. Again these contain their arity but don't need a Unique.
540 There should be a magic way of generating the info tables and
541 entry code for all tuples.
543 But at the moment we just compile a Haskell source
544 file\srcloc{lib/prelude/...} containing declarations like:
547 data Tuple2 a b = Tup2 a b
548 data Tuple3 a b c = Tup3 a b c
549 data Tuple4 a b c d = Tup4 a b c d
552 The print-names associated with the magic @Id@s for tuple constructors
553 ``just happen'' to be the same as those generated by these
557 The instance environment should have a magic way to know
558 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
559 so on. \ToDo{Not implemented yet.}
562 There should also be a way to generate the appropriate code for each
563 of these instances, but (like the info tables and entry code) it is
564 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
568 mkTupleTy :: Boxity -> Int -> [Type] -> Type
569 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
571 unitTy = mkTupleTy Boxed 0 []