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 ( mkPrelModule )
95 import Name ( Name, nameRdrName, nameUnique, nameOccName,
96 nameModule, mkWiredInName )
97 import OccName ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
98 import RdrName ( rdrNameOcc )
99 import DataCon ( DataCon, StrictnessMark(..), mkDataCon, dataConId )
100 import Var ( TyVar, tyVarKind )
101 import TyCon ( TyCon, AlgTyConFlavour(..), tyConDataCons,
102 mkTupleTyCon, isUnLiftedTyCon, mkAlgTyCon
105 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
107 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTys,
108 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
109 splitTyConApp_maybe, repType,
110 TauType, ClassContext )
111 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
116 alpha_tyvar = [alphaTyVar]
118 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
122 %************************************************************************
124 \subsection{Wired in type constructors}
126 %************************************************************************
129 wiredInTyCons :: [TyCon]
130 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
132 data_tycons = genericTyCons ++
144 genericTyCons :: [TyCon]
145 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
148 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..37] ]
149 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..37] ]
153 %************************************************************************
155 \subsection{mkWiredInTyCon}
157 %************************************************************************
160 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
161 pcRecDataTyCon = pcTyCon DataTyCon Recursive
163 pcTyCon new_or_data is_rec name tyvars argvrcs cons
166 tycon = mkAlgTyCon name kind
172 [] -- No record selectors
177 mod = nameModule name
178 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
179 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
181 -- We generate names for the generic to/from Ids by incrementing
182 -- the TyCon unique. So each Prelude tycon needs 3 slots, one
183 -- for itself and two more for the generic Ids.
184 mk_tc_gen_info mod tc_uniq tc_name tycon
185 = mkTyConGenInfo tycon [name1, name2]
187 tc_occ_name = nameOccName tc_name
188 occ_name1 = mkGenOcc1 tc_occ_name
189 occ_name2 = mkGenOcc2 tc_occ_name
190 fn1_key = incrUnique tc_uniq
191 fn2_key = incrUnique fn1_key
192 name1 = mkWiredInName mod occ_name1 fn1_key
193 name2 = mkWiredInName mod occ_name2 fn2_key
195 pcDataCon :: Name -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
196 -- The unique is the first of two free uniques;
197 -- the first is used for the datacon itself and the worker;
198 -- the second is used for the wrapper.
200 pcDataCon name tyvars context arg_tys tycon
203 data_con = mkDataCon name
204 [ NotMarkedStrict | a <- arg_tys ]
205 [ {- no labelled fields -} ]
206 tyvars context [] [] arg_tys tycon work_id wrap_id
208 wrap_rdr = nameRdrName name
209 wrap_occ = rdrNameOcc wrap_rdr
211 mod = nameModule name
212 wrap_id = mkDataConWrapId data_con
214 work_occ = mkWorkerOcc wrap_occ
215 work_key = incrUnique (nameUnique name)
216 work_name = mkWiredInName mod work_occ work_key
217 work_id = mkDataConId work_name data_con
221 %************************************************************************
223 \subsection[TysWiredIn-tuples]{The tuple types}
225 %************************************************************************
228 tupleTyCon :: Boxity -> Arity -> TyCon
229 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
230 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
231 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
233 tupleCon :: Boxity -> Arity -> DataCon
234 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
235 tupleCon Boxed i = snd (boxedTupleArr ! i)
236 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
238 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
239 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
240 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
242 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
243 mk_tuple boxity arity = (tycon, tuple_con)
245 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
246 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
247 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
248 res_kind | isBoxed boxity = boxedTypeKind
249 | otherwise = unboxedTypeKind
251 tyvars | isBoxed boxity = take arity alphaTyVars
252 | otherwise = take arity openAlphaTyVars
254 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
255 tyvar_tys = mkTyVarTys tyvars
256 (mod_name, name_str) = mkTupNameStr boxity arity
257 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
258 tc_uniq = mkTupleTyConUnique boxity arity
259 dc_uniq = mkTupleDataConUnique boxity arity
260 mod = mkPrelModule mod_name
261 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
263 unitTyCon = tupleTyCon Boxed 0
264 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
266 pairTyCon = tupleTyCon Boxed 2
268 unboxedSingletonTyCon = tupleTyCon Unboxed 1
269 unboxedSingletonDataCon = tupleCon Unboxed 1
271 unboxedPairTyCon = tupleTyCon Unboxed 2
272 unboxedPairDataCon = tupleCon Unboxed 2
275 %************************************************************************
277 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
279 %************************************************************************
282 -- The Void type is represented as a data type with no constructors
283 -- It's a built in type (i.e. there's no way to define it in Haskell;
284 -- the nearest would be
286 -- data Void = -- No constructors!
288 -- ) It's boxed; there is only one value of this
289 -- type, namely "void", whose semantics is just bottom.
291 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
298 charTy = mkTyConTy charTyCon
300 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
301 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
303 stringTy = mkListTy charTy -- convenience only
307 intTy = mkTyConTy intTyCon
309 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
310 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
312 isIntTy :: Type -> Bool
313 isIntTy = isTyCon intTyConKey
318 wordTy = mkTyConTy wordTyCon
320 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
321 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
325 addrTy = mkTyConTy addrTyCon
327 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
328 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
330 isAddrTy :: Type -> Bool
331 isAddrTy = isTyCon addrTyConKey
335 floatTy = mkTyConTy floatTyCon
337 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
338 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
340 isFloatTy :: Type -> Bool
341 isFloatTy = isTyCon floatTyConKey
345 doubleTy = mkTyConTy doubleTyCon
347 isDoubleTy :: Type -> Bool
348 isDoubleTy = isTyCon doubleTyConKey
350 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
351 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
356 = pcNonRecDataTyCon stablePtrTyConName
357 alpha_tyvar [(True,False)] [stablePtrDataCon]
360 = pcDataCon stablePtrDataConName
361 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
366 = pcNonRecDataTyCon foreignObjTyConName
367 [] [] [foreignObjDataCon]
370 = pcDataCon foreignObjDataConName
371 [] [] [foreignObjPrimTy] foreignObjTyCon
373 isForeignObjTy :: Type -> Bool
374 isForeignObjTy = isTyCon foreignObjTyConKey
377 %************************************************************************
379 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
381 %************************************************************************
383 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
386 integerTy = mkTyConTy integerTyCon
388 integerTyCon = pcNonRecDataTyCon integerTyConName
389 [] [] [smallIntegerDataCon, largeIntegerDataCon]
391 smallIntegerDataCon = pcDataCon smallIntegerDataConName
392 [] [] [intPrimTy] integerTyCon
393 largeIntegerDataCon = pcDataCon largeIntegerDataConName
394 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
397 isIntegerTy :: Type -> Bool
398 isIntegerTy = isTyCon integerTyConKey
402 %************************************************************************
404 \subsection[TysWiredIn-ext-type]{External types}
406 %************************************************************************
408 The compiler's foreign function interface supports the passing of a
409 restricted set of types as arguments and results (the restricting factor
413 isFFIArgumentTy :: DynFlags -> Bool -> Type -> Bool
414 -- Checks for valid argument type for a 'foreign import'
415 isFFIArgumentTy dflags is_safe ty
416 = checkRepTyCon (legalOutgoingTyCon dflags is_safe) ty
418 isFFIExternalTy :: Type -> Bool
419 -- Types that are allowed as arguments of a 'foreign export'
420 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
422 isFFIResultTy :: Type -> Bool
423 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
424 -- Maybe we should distinguish between import and export, but
425 -- here we just choose the more restrictive 'incoming' predicate
426 -- But we allow () as well
427 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
429 isFFIDynArgumentTy :: Type -> Bool
430 -- The argument type of a foreign import dynamic must be either Addr, or
431 -- a newtype of Addr.
432 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
434 isFFIDynResultTy :: Type -> Bool
435 -- The result type of a foreign export dynamic must be either Addr, or
436 -- a newtype of Addr.
437 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
439 isFFILabelTy :: Type -> Bool
440 -- The type of a foreign label must be either Addr, or
441 -- a newtype of Addr.
442 isFFILabelTy = checkRepTyCon (== addrTyCon)
444 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
445 -- look through newtypes
446 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
448 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
449 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
450 Just (tycon, _) -> check_tc tycon
453 isTyCon :: Unique -> Type -> Bool
454 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
457 ----------------------------------------------
458 These chaps do the work; they are not exported
459 ----------------------------------------------
462 legalIncomingTyCon :: TyCon -> Bool
463 -- It's illegal to return foreign objects and (mutable)
464 -- bytearrays from a _ccall_ / foreign declaration
465 -- (or be passed them as arguments in foreign exported functions).
466 legalIncomingTyCon tc
467 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey,
468 mutableByteArrayTyConKey ]
470 -- It's also illegal to make foreign exports that take unboxed
471 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
473 = boxedMarshalableTyCon tc
475 legalOutgoingTyCon :: DynFlags -> Bool -> TyCon -> Bool
476 -- Checks validity of types going from Haskell -> external world
477 -- The boolean is true for a 'safe' call (when we don't want to
478 -- pass Haskell pointers to the world)
479 legalOutgoingTyCon dflags be_safe tc
480 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
483 = marshalableTyCon dflags tc
485 marshalableTyCon dflags tc
486 = (dopt Opt_GlasgowExts dflags && isUnLiftedTyCon tc)
487 || boxedMarshalableTyCon tc
489 boxedMarshalableTyCon tc
490 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
491 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
492 , floatTyConKey, doubleTyConKey
493 , addrTyConKey, charTyConKey, foreignObjTyConKey
495 , byteArrayTyConKey, mutableByteArrayTyConKey
501 %************************************************************************
503 \subsection[TysWiredIn-Bool]{The @Bool@ type}
505 %************************************************************************
507 An ordinary enumeration type, but deeply wired in. There are no
508 magical operations on @Bool@ (just the regular Prelude code).
510 {\em BEGIN IDLE SPECULATION BY SIMON}
512 This is not the only way to encode @Bool@. A more obvious coding makes
513 @Bool@ just a boxed up version of @Bool#@, like this:
516 data Bool = MkBool Bool#
519 Unfortunately, this doesn't correspond to what the Report says @Bool@
520 looks like! Furthermore, we get slightly less efficient code (I
521 think) with this coding. @gtInt@ would look like this:
524 gtInt :: Int -> Int -> Bool
525 gtInt x y = case x of I# x# ->
527 case (gtIntPrim x# y#) of
531 Notice that the result of the @gtIntPrim@ comparison has to be turned
532 into an integer (here called @b#@), and returned in a @MkBool@ box.
534 The @if@ expression would compile to this:
537 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
540 I think this code is a little less efficient than the previous code,
541 but I'm not certain. At all events, corresponding with the Report is
542 important. The interesting thing is that the language is expressive
543 enough to describe more than one alternative; and that a type doesn't
544 necessarily need to be a straightforwardly boxed version of its
545 primitive counterpart.
547 {\em END IDLE SPECULATION BY SIMON}
550 boolTy = mkTyConTy boolTyCon
552 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
553 [] [] [falseDataCon, trueDataCon]
555 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
556 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
558 falseDataConId = dataConId falseDataCon
559 trueDataConId = dataConId trueDataCon
562 %************************************************************************
564 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
566 %************************************************************************
568 Special syntax, deeply wired in, but otherwise an ordinary algebraic
571 data [] a = [] | a : (List a)
573 data (,) a b = (,,) a b
578 mkListTy :: Type -> Type
579 mkListTy ty = mkTyConApp listTyCon [ty]
581 listTyCon = pcRecDataTyCon listTyConName
582 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
584 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
585 consDataCon = pcDataCon consDataConName
586 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
587 -- Interesting: polymorphic recursion would help here.
588 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
589 -- gets the over-specific type (Type -> Type)
592 %************************************************************************
594 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
596 %************************************************************************
598 The tuple types are definitely magic, because they form an infinite
603 They have a special family of type constructors, of type @TyCon@
604 These contain the tycon arity, but don't require a Unique.
607 They have a special family of constructors, of type
608 @Id@. Again these contain their arity but don't need a Unique.
611 There should be a magic way of generating the info tables and
612 entry code for all tuples.
614 But at the moment we just compile a Haskell source
615 file\srcloc{lib/prelude/...} containing declarations like:
618 data Tuple2 a b = Tup2 a b
619 data Tuple3 a b c = Tup3 a b c
620 data Tuple4 a b c d = Tup4 a b c d
623 The print-names associated with the magic @Id@s for tuple constructors
624 ``just happen'' to be the same as those generated by these
628 The instance environment should have a magic way to know
629 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
630 so on. \ToDo{Not implemented yet.}
633 There should also be a way to generate the appropriate code for each
634 of these instances, but (like the info tables and entry code) it is
635 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
639 mkTupleTy :: Boxity -> Int -> [Type] -> Type
640 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
642 unitTy = mkTupleTy Boxed 0 []
645 %************************************************************************
647 \subsection{Wired In Type Constructors for Representation Types}
649 %************************************************************************
651 The following code defines the wired in datatypes cross, plus, unit
652 and c_of needed for the generic methods.
654 Ok, so the basic story is that for each type constructor I need to
655 create 2 things - a TyCon and a DataCon and then we are basically
656 ok. There are going to be no arguments passed to these functions
657 because -well- there is nothing to pass to these functions.
661 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
663 crossDataCon :: DataCon
664 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
667 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
669 inlDataCon, inrDataCon :: DataCon
670 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
671 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
673 genUnitTyCon :: TyCon -- The "1" type constructor for generics
674 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
676 genUnitDataCon :: DataCon
677 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon