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.''
14 wiredInTyCons, genericTyCons,
29 falseDataCon, falseDataConId,
54 unitTyCon, unitDataConId, pairTyCon,
55 unboxedSingletonTyCon, unboxedSingletonDataCon,
56 unboxedPairTyCon, unboxedPairDataCon,
59 genUnitTyCon, genUnitDataCon,
60 plusTyCon, inrDataCon, inlDataCon,
61 crossTyCon, crossDataCon,
65 trueDataCon, trueDataConId,
72 isFFIArgumentTy, -- :: Bool -> Type -> Bool
73 isFFIResultTy, -- :: Type -> Bool
74 isFFIExternalTy, -- :: Type -> Bool
75 isFFIDynArgumentTy, -- :: Type -> Bool
76 isFFIDynResultTy, -- :: Type -> Bool
77 isFFILabelTy, -- :: Type -> Bool
78 isAddrTy, -- :: Type -> Bool
79 isForeignObjTy -- :: Type -> Bool
83 #include "HsVersions.h"
85 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
86 import {-# SOURCE #-} Generics( mkTyConGenInfo )
93 import Constants ( mAX_TUPLE_SIZE )
94 import Module ( Module, mkPrelModule )
95 import Name ( mkWiredInTyConName, mkWiredInIdName, nameOccName )
96 import OccName ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
97 import RdrName ( RdrName, mkPreludeQual, rdrNameOcc, rdrNameModule )
98 import DataCon ( DataCon, StrictnessMark(..), mkDataCon, dataConId )
99 import Var ( TyVar, tyVarKind )
100 import TyCon ( TyCon, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
101 mkSynTyCon, mkTupleTyCon,
102 isUnLiftedTyCon, mkAlgTyConRep,tyConName
105 import BasicTypes ( Arity, RecFlag(..), EP(..), Boxity(..), isBoxed )
107 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
108 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
110 splitTyConApp_maybe, repType, mkTyVarTy,
111 TauType, ClassContext )
112 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
114 import CmdLineOpts ( DynFlags, dopt_GlasgowExts )
116 import Maybe ( fromJust )
117 import FiniteMap ( lookupFM )
119 alpha_tyvar = [alphaTyVar]
121 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
125 %************************************************************************
127 \subsection{Wired in type constructors}
129 %************************************************************************
132 wiredInTyCons :: [TyCon]
133 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
135 data_tycons = genericTyCons ++
147 genericTyCons :: [TyCon]
148 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
151 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..37] ]
152 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..37] ]
156 %************************************************************************
158 \subsection{mkWiredInTyCon}
160 %************************************************************************
163 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
164 pcRecDataTyCon = pcTyCon DataTyCon Recursive
166 pcTyCon new_or_data is_rec key rdr_name tyvars argvrcs cons
169 tycon = mkAlgTyConRep name kind
180 mod = mkPrelModule (rdrNameModule rdr_name)
181 occ = rdrNameOcc rdr_name
182 name = mkWiredInTyConName key mod occ tycon
183 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
184 gen_info = mk_tc_gen_info mod key name tycon
186 pcDataCon :: Unique -- DataConKey
187 -> RdrName -- Qualified
188 -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
189 -- The unique is the first of two free uniques;
190 -- the first is used for the datacon itself and the worker;
191 -- the second is used for the wrapper.
193 pcDataCon wrap_key rdr_name tyvars context arg_tys tycon
196 mod = mkPrelModule (rdrNameModule rdr_name)
197 wrap_occ = rdrNameOcc rdr_name
199 data_con = mkDataCon wrap_name
200 [ NotMarkedStrict | a <- arg_tys ]
201 [ {- no labelled fields -} ]
202 tyvars context [] [] arg_tys tycon work_id wrap_id
204 work_occ = mkWorkerOcc wrap_occ
205 work_key = incrUnique wrap_key
206 work_name = mkWiredInIdName work_key mod work_occ work_id
207 work_id = mkDataConId work_name data_con
209 wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
210 wrap_id = mkDataConWrapId data_con
214 %************************************************************************
216 \subsection[TysWiredIn-tuples]{The tuple types}
218 %************************************************************************
221 tupleTyCon :: Boxity -> Arity -> TyCon
222 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
223 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
224 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
226 tupleCon :: Boxity -> Arity -> DataCon
227 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
228 tupleCon Boxed i = snd (boxedTupleArr ! i)
229 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
231 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
232 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
233 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
235 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
236 mk_tuple boxity arity = (tycon, tuple_con)
238 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
239 tc_name = mkWiredInTyConName tc_uniq mod (mkOccFS tcName name_str) tycon
240 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
241 res_kind | isBoxed boxity = boxedTypeKind
242 | otherwise = unboxedTypeKind
244 tyvars | isBoxed boxity = take arity alphaTyVars
245 | otherwise = take arity openAlphaTyVars
247 tuple_con = pcDataCon dc_uniq rdr_name tyvars [] tyvar_tys tycon
248 tyvar_tys = mkTyVarTys tyvars
249 (mod_name, name_str) = mkTupNameStr boxity arity
250 rdr_name = mkPreludeQual dataName mod_name name_str
251 tc_uniq = mkTupleTyConUnique boxity arity
252 dc_uniq = mkTupleDataConUnique boxity arity
253 mod = mkPrelModule mod_name
254 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
256 mk_tc_gen_info mod tc_uniq tc_name tycon
259 tc_occ_name = nameOccName tc_name
260 occ_name1 = mkGenOcc1 tc_occ_name
261 occ_name2 = mkGenOcc2 tc_occ_name
262 fn1_key = incrUnique tc_uniq
263 fn2_key = incrUnique fn1_key
264 name1 = mkWiredInIdName fn1_key mod occ_name1 id1
265 name2 = mkWiredInIdName fn2_key mod occ_name2 id2
266 gen_info = mkTyConGenInfo tycon name1 name2
267 Just (EP id1 id2) = gen_info
269 unitTyCon = tupleTyCon Boxed 0
270 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
272 pairTyCon = tupleTyCon Boxed 2
274 unboxedSingletonTyCon = tupleTyCon Unboxed 1
275 unboxedSingletonDataCon = tupleCon Unboxed 1
277 unboxedPairTyCon = tupleTyCon Unboxed 2
278 unboxedPairDataCon = tupleCon Unboxed 2
281 %************************************************************************
283 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
285 %************************************************************************
288 -- The Void type is represented as a data type with no constructors
289 -- It's a built in type (i.e. there's no way to define it in Haskell;
290 -- the nearest would be
292 -- data Void = -- No constructors!
294 -- ) It's boxed; there is only one value of this
295 -- type, namely "void", whose semantics is just bottom.
297 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
304 charTy = mkTyConTy charTyCon
306 charTyCon = pcNonRecDataTyCon charTyConKey charTyCon_RDR [] [] [charDataCon]
307 charDataCon = pcDataCon charDataConKey charDataCon_RDR [] [] [charPrimTy] charTyCon
309 stringTy = mkListTy charTy -- convenience only
313 intTy = mkTyConTy intTyCon
315 intTyCon = pcNonRecDataTyCon intTyConKey intTyCon_RDR [] [] [intDataCon]
316 intDataCon = pcDataCon intDataConKey mkInt_RDR [] [] [intPrimTy] intTyCon
318 isIntTy :: Type -> Bool
319 isIntTy = isTyCon intTyConKey
324 wordTy = mkTyConTy wordTyCon
326 wordTyCon = pcNonRecDataTyCon wordTyConKey wordTyCon_RDR [] [] [wordDataCon]
327 wordDataCon = pcDataCon wordDataConKey wordDataCon_RDR [] [] [wordPrimTy] wordTyCon
331 addrTy = mkTyConTy addrTyCon
333 addrTyCon = pcNonRecDataTyCon addrTyConKey addrTyCon_RDR [] [] [addrDataCon]
334 addrDataCon = pcDataCon addrDataConKey addrDataCon_RDR [] [] [addrPrimTy] addrTyCon
336 isAddrTy :: Type -> Bool
337 isAddrTy = isTyCon addrTyConKey
341 floatTy = mkTyConTy floatTyCon
343 floatTyCon = pcNonRecDataTyCon floatTyConKey floatTyCon_RDR [] [] [floatDataCon]
344 floatDataCon = pcDataCon floatDataConKey floatDataCon_RDR [] [] [floatPrimTy] floatTyCon
346 isFloatTy :: Type -> Bool
347 isFloatTy = isTyCon floatTyConKey
351 doubleTy = mkTyConTy doubleTyCon
353 isDoubleTy :: Type -> Bool
354 isDoubleTy = isTyCon doubleTyConKey
356 doubleTyCon = pcNonRecDataTyCon doubleTyConKey doubleTyCon_RDR [] [] [doubleDataCon]
357 doubleDataCon = pcDataCon doubleDataConKey doubleDataCon_RDR [] [] [doublePrimTy] doubleTyCon
362 = pcNonRecDataTyCon stablePtrTyConKey stablePtrTyCon_RDR
363 alpha_tyvar [(True,False)] [stablePtrDataCon]
366 = pcDataCon stablePtrDataConKey stablePtrDataCon_RDR
367 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
372 = pcNonRecDataTyCon foreignObjTyConKey foreignObjTyCon_RDR
373 [] [] [foreignObjDataCon]
376 = pcDataCon foreignObjDataConKey foreignObjDataCon_RDR
377 [] [] [foreignObjPrimTy] foreignObjTyCon
379 isForeignObjTy :: Type -> Bool
380 isForeignObjTy = isTyCon foreignObjTyConKey
383 %************************************************************************
385 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
387 %************************************************************************
389 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
392 integerTy = mkTyConTy integerTyCon
394 integerTyCon = pcNonRecDataTyCon integerTyConKey integerTyCon_RDR
395 [] [] [smallIntegerDataCon, largeIntegerDataCon]
397 smallIntegerDataCon = pcDataCon smallIntegerDataConKey smallIntegerDataCon_RDR
398 [] [] [intPrimTy] integerTyCon
399 largeIntegerDataCon = pcDataCon largeIntegerDataConKey largeIntegerDataCon_RDR
400 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
403 isIntegerTy :: Type -> Bool
404 isIntegerTy = isTyCon integerTyConKey
408 %************************************************************************
410 \subsection[TysWiredIn-ext-type]{External types}
412 %************************************************************************
414 The compiler's foreign function interface supports the passing of a
415 restricted set of types as arguments and results (the restricting factor
419 isFFIArgumentTy :: DynFlags -> Bool -> Type -> Bool
420 -- Checks for valid argument type for a 'foreign import'
421 isFFIArgumentTy dflags is_safe ty
422 = checkRepTyCon (legalOutgoingTyCon dflags is_safe) ty
424 isFFIExternalTy :: Type -> Bool
425 -- Types that are allowed as arguments of a 'foreign export'
426 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
428 isFFIResultTy :: Type -> Bool
429 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
430 -- Maybe we should distinguish between import and export, but
431 -- here we just choose the more restrictive 'incoming' predicate
432 -- But we allow () as well
433 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
435 isFFIDynArgumentTy :: Type -> Bool
436 -- The argument type of a foreign import dynamic must be either Addr, or
437 -- a newtype of Addr.
438 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
440 isFFIDynResultTy :: Type -> Bool
441 -- The result type of a foreign export dynamic must be either Addr, or
442 -- a newtype of Addr.
443 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
445 isFFILabelTy :: Type -> Bool
446 -- The type of a foreign label must be either Addr, or
447 -- a newtype of Addr.
448 isFFILabelTy = checkRepTyCon (== addrTyCon)
450 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
451 -- look through newtypes
452 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
454 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
455 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
456 Just (tycon, _) -> check_tc tycon
459 isTyCon :: Unique -> Type -> Bool
460 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
463 ----------------------------------------------
464 These chaps do the work; they are not exported
465 ----------------------------------------------
468 legalIncomingTyCon :: TyCon -> Bool
469 -- It's illegal to return foreign objects and (mutable)
470 -- bytearrays from a _ccall_ / foreign declaration
471 -- (or be passed them as arguments in foreign exported functions).
472 legalIncomingTyCon tc
473 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey,
474 mutableByteArrayTyConKey ]
476 -- It's also illegal to make foreign exports that take unboxed
477 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
479 = boxedMarshalableTyCon tc
481 legalOutgoingTyCon :: DynFlags -> Bool -> TyCon -> Bool
482 -- Checks validity of types going from Haskell -> external world
483 -- The boolean is true for a 'safe' call (when we don't want to
484 -- pass Haskell pointers to the world)
485 legalOutgoingTyCon dflags be_safe tc
486 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
489 = marshalableTyCon dflags tc
491 marshalableTyCon dflags tc
492 = (dopt_GlasgowExts dflags && isUnLiftedTyCon tc)
493 || boxedMarshalableTyCon tc
495 boxedMarshalableTyCon tc
496 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
497 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
498 , floatTyConKey, doubleTyConKey
499 , addrTyConKey, charTyConKey, foreignObjTyConKey
501 , byteArrayTyConKey, mutableByteArrayTyConKey
507 %************************************************************************
509 \subsection[TysWiredIn-Bool]{The @Bool@ type}
511 %************************************************************************
513 An ordinary enumeration type, but deeply wired in. There are no
514 magical operations on @Bool@ (just the regular Prelude code).
516 {\em BEGIN IDLE SPECULATION BY SIMON}
518 This is not the only way to encode @Bool@. A more obvious coding makes
519 @Bool@ just a boxed up version of @Bool#@, like this:
522 data Bool = MkBool Bool#
525 Unfortunately, this doesn't correspond to what the Report says @Bool@
526 looks like! Furthermore, we get slightly less efficient code (I
527 think) with this coding. @gtInt@ would look like this:
530 gtInt :: Int -> Int -> Bool
531 gtInt x y = case x of I# x# ->
533 case (gtIntPrim x# y#) of
537 Notice that the result of the @gtIntPrim@ comparison has to be turned
538 into an integer (here called @b#@), and returned in a @MkBool@ box.
540 The @if@ expression would compile to this:
543 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
546 I think this code is a little less efficient than the previous code,
547 but I'm not certain. At all events, corresponding with the Report is
548 important. The interesting thing is that the language is expressive
549 enough to describe more than one alternative; and that a type doesn't
550 necessarily need to be a straightforwardly boxed version of its
551 primitive counterpart.
553 {\em END IDLE SPECULATION BY SIMON}
556 boolTy = mkTyConTy boolTyCon
558 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey
559 boolTyCon_RDR [] [] [falseDataCon, trueDataCon]
561 falseDataCon = pcDataCon falseDataConKey false_RDR [] [] [] boolTyCon
562 trueDataCon = pcDataCon trueDataConKey true_RDR [] [] [] boolTyCon
564 falseDataConId = dataConId falseDataCon
565 trueDataConId = dataConId trueDataCon
568 %************************************************************************
570 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
572 %************************************************************************
574 Special syntax, deeply wired in, but otherwise an ordinary algebraic
577 data [] a = [] | a : (List a)
579 data (,) a b = (,,) a b
584 mkListTy :: Type -> Type
585 mkListTy ty = mkTyConApp listTyCon [ty]
587 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
589 listTyCon = pcRecDataTyCon listTyConKey listTyCon_RDR
590 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
592 nilDataCon = pcDataCon nilDataConKey nil_RDR alpha_tyvar [] [] listTyCon
593 consDataCon = pcDataCon consDataConKey cons_RDR
594 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
595 -- Interesting: polymorphic recursion would help here.
596 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
597 -- gets the over-specific type (Type -> Type)
600 %************************************************************************
602 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
604 %************************************************************************
606 The tuple types are definitely magic, because they form an infinite
611 They have a special family of type constructors, of type @TyCon@
612 These contain the tycon arity, but don't require a Unique.
615 They have a special family of constructors, of type
616 @Id@. Again these contain their arity but don't need a Unique.
619 There should be a magic way of generating the info tables and
620 entry code for all tuples.
622 But at the moment we just compile a Haskell source
623 file\srcloc{lib/prelude/...} containing declarations like:
626 data Tuple2 a b = Tup2 a b
627 data Tuple3 a b c = Tup3 a b c
628 data Tuple4 a b c d = Tup4 a b c d
631 The print-names associated with the magic @Id@s for tuple constructors
632 ``just happen'' to be the same as those generated by these
636 The instance environment should have a magic way to know
637 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
638 so on. \ToDo{Not implemented yet.}
641 There should also be a way to generate the appropriate code for each
642 of these instances, but (like the info tables and entry code) it is
643 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
647 mkTupleTy :: Boxity -> Int -> [Type] -> Type
648 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
650 unitTy = mkTupleTy Boxed 0 []
653 %************************************************************************
655 \subsection{Wired In Type Constructors for Representation Types}
657 %************************************************************************
659 The following code defines the wired in datatypes cross, plus, unit
660 and c_of needed for the generic methods.
662 Ok, so the basic story is that for each type constructor I need to
663 create 2 things - a TyCon and a DataCon and then we are basically
664 ok. There are going to be no arguments passed to these functions
665 because -well- there is nothing to pass to these functions.
669 crossTyCon = pcNonRecDataTyCon crossTyConKey crossTyCon_RDR alpha_beta_tyvars [] [crossDataCon]
671 crossDataCon :: DataCon
672 crossDataCon = pcDataCon crossDataConKey crossDataCon_RDR alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
675 plusTyCon = pcNonRecDataTyCon plusTyConKey plusTyCon_RDR alpha_beta_tyvars [] [inlDataCon, inrDataCon]
677 inlDataCon, inrDataCon :: DataCon
678 inlDataCon = pcDataCon inlDataConKey inlDataCon_RDR alpha_beta_tyvars [] [alphaTy] plusTyCon
679 inrDataCon = pcDataCon inrDataConKey inrDataCon_RDR alpha_beta_tyvars [] [betaTy] plusTyCon
681 genUnitTyCon :: TyCon -- The "1" type constructor for generics
682 genUnitTyCon = pcNonRecDataTyCon genUnitTyConKey genUnitTyCon_RDR [] [] [genUnitDataCon]
684 genUnitDataCon :: DataCon
685 genUnitDataCon = pcDataCon genUnitDataConKey genUnitDataCon_RDR [] [] [] genUnitTyCon