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 isForeignPtrTy -- :: 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
379 = pcNonRecDataTyCon foreignPtrTyConName
380 alpha_tyvar [(True,False)] [foreignPtrDataCon]
383 = pcDataCon foreignPtrDataConName
384 alpha_tyvar [] [foreignObjPrimTy] foreignPtrTyCon
386 isForeignPtrTy :: Type -> Bool
387 isForeignPtrTy = isTyCon foreignPtrTyConKey
390 %************************************************************************
392 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
394 %************************************************************************
396 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
399 integerTy = mkTyConTy integerTyCon
401 integerTyCon = pcNonRecDataTyCon integerTyConName
402 [] [] [smallIntegerDataCon, largeIntegerDataCon]
404 smallIntegerDataCon = pcDataCon smallIntegerDataConName
405 [] [] [intPrimTy] integerTyCon
406 largeIntegerDataCon = pcDataCon largeIntegerDataConName
407 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
410 isIntegerTy :: Type -> Bool
411 isIntegerTy = isTyCon integerTyConKey
415 %************************************************************************
417 \subsection[TysWiredIn-ext-type]{External types}
419 %************************************************************************
421 The compiler's foreign function interface supports the passing of a
422 restricted set of types as arguments and results (the restricting factor
426 isFFIArgumentTy :: DynFlags -> Bool -> Type -> Bool
427 -- Checks for valid argument type for a 'foreign import'
428 isFFIArgumentTy dflags is_safe ty
429 = checkRepTyCon (legalOutgoingTyCon dflags is_safe) ty
431 isFFIExternalTy :: Type -> Bool
432 -- Types that are allowed as arguments of a 'foreign export'
433 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
435 isFFIResultTy :: Type -> Bool
436 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
437 -- Maybe we should distinguish between import and export, but
438 -- here we just choose the more restrictive 'incoming' predicate
439 -- But we allow () as well
440 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
442 isFFIDynArgumentTy :: Type -> Bool
443 -- The argument type of a foreign import dynamic must be either Addr, or
444 -- a newtype of Addr.
445 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
447 isFFIDynResultTy :: Type -> Bool
448 -- The result type of a foreign export dynamic must be either Addr, or
449 -- a newtype of Addr.
450 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
452 isFFILabelTy :: Type -> Bool
453 -- The type of a foreign label must be either Addr, or
454 -- a newtype of Addr.
455 isFFILabelTy = checkRepTyCon (== addrTyCon)
457 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
458 -- look through newtypes
459 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
461 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
462 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
463 Just (tycon, _) -> check_tc tycon
466 isTyCon :: Unique -> Type -> Bool
467 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
470 ----------------------------------------------
471 These chaps do the work; they are not exported
472 ----------------------------------------------
475 legalIncomingTyCon :: TyCon -> Bool
476 -- It's illegal to return foreign objects and (mutable)
477 -- bytearrays from a _ccall_ / foreign declaration
478 -- (or be passed them as arguments in foreign exported functions).
479 legalIncomingTyCon tc
480 | getUnique tc `elem` [ foreignObjTyConKey, foreignPtrTyConKey,
481 byteArrayTyConKey, mutableByteArrayTyConKey ]
483 -- It's also illegal to make foreign exports that take unboxed
484 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
486 = boxedMarshalableTyCon tc
488 legalOutgoingTyCon :: DynFlags -> Bool -> TyCon -> Bool
489 -- Checks validity of types going from Haskell -> external world
490 -- The boolean is true for a 'safe' call (when we don't want to
491 -- pass Haskell pointers to the world)
492 legalOutgoingTyCon dflags be_safe tc
493 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
496 = marshalableTyCon dflags tc
498 marshalableTyCon dflags tc
499 = (dopt Opt_GlasgowExts dflags && isUnLiftedTyCon tc)
500 || boxedMarshalableTyCon tc
502 boxedMarshalableTyCon tc
503 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
504 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
505 , floatTyConKey, doubleTyConKey
506 , addrTyConKey, charTyConKey, foreignObjTyConKey
509 , byteArrayTyConKey, mutableByteArrayTyConKey
515 %************************************************************************
517 \subsection[TysWiredIn-Bool]{The @Bool@ type}
519 %************************************************************************
521 An ordinary enumeration type, but deeply wired in. There are no
522 magical operations on @Bool@ (just the regular Prelude code).
524 {\em BEGIN IDLE SPECULATION BY SIMON}
526 This is not the only way to encode @Bool@. A more obvious coding makes
527 @Bool@ just a boxed up version of @Bool#@, like this:
530 data Bool = MkBool Bool#
533 Unfortunately, this doesn't correspond to what the Report says @Bool@
534 looks like! Furthermore, we get slightly less efficient code (I
535 think) with this coding. @gtInt@ would look like this:
538 gtInt :: Int -> Int -> Bool
539 gtInt x y = case x of I# x# ->
541 case (gtIntPrim x# y#) of
545 Notice that the result of the @gtIntPrim@ comparison has to be turned
546 into an integer (here called @b#@), and returned in a @MkBool@ box.
548 The @if@ expression would compile to this:
551 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
554 I think this code is a little less efficient than the previous code,
555 but I'm not certain. At all events, corresponding with the Report is
556 important. The interesting thing is that the language is expressive
557 enough to describe more than one alternative; and that a type doesn't
558 necessarily need to be a straightforwardly boxed version of its
559 primitive counterpart.
561 {\em END IDLE SPECULATION BY SIMON}
564 boolTy = mkTyConTy boolTyCon
566 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
567 [] [] [falseDataCon, trueDataCon]
569 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
570 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
572 falseDataConId = dataConId falseDataCon
573 trueDataConId = dataConId trueDataCon
576 %************************************************************************
578 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
580 %************************************************************************
582 Special syntax, deeply wired in, but otherwise an ordinary algebraic
585 data [] a = [] | a : (List a)
587 data (,) a b = (,,) a b
592 mkListTy :: Type -> Type
593 mkListTy ty = mkTyConApp listTyCon [ty]
595 listTyCon = pcRecDataTyCon listTyConName
596 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
598 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
599 consDataCon = pcDataCon consDataConName
600 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
601 -- Interesting: polymorphic recursion would help here.
602 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
603 -- gets the over-specific type (Type -> Type)
606 %************************************************************************
608 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
610 %************************************************************************
612 The tuple types are definitely magic, because they form an infinite
617 They have a special family of type constructors, of type @TyCon@
618 These contain the tycon arity, but don't require a Unique.
621 They have a special family of constructors, of type
622 @Id@. Again these contain their arity but don't need a Unique.
625 There should be a magic way of generating the info tables and
626 entry code for all tuples.
628 But at the moment we just compile a Haskell source
629 file\srcloc{lib/prelude/...} containing declarations like:
632 data Tuple2 a b = Tup2 a b
633 data Tuple3 a b c = Tup3 a b c
634 data Tuple4 a b c d = Tup4 a b c d
637 The print-names associated with the magic @Id@s for tuple constructors
638 ``just happen'' to be the same as those generated by these
642 The instance environment should have a magic way to know
643 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
644 so on. \ToDo{Not implemented yet.}
647 There should also be a way to generate the appropriate code for each
648 of these instances, but (like the info tables and entry code) it is
649 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
653 mkTupleTy :: Boxity -> Int -> [Type] -> Type
654 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
656 unitTy = mkTupleTy Boxed 0 []
659 %************************************************************************
661 \subsection{Wired In Type Constructors for Representation Types}
663 %************************************************************************
665 The following code defines the wired in datatypes cross, plus, unit
666 and c_of needed for the generic methods.
668 Ok, so the basic story is that for each type constructor I need to
669 create 2 things - a TyCon and a DataCon and then we are basically
670 ok. There are going to be no arguments passed to these functions
671 because -well- there is nothing to pass to these functions.
675 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
677 crossDataCon :: DataCon
678 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
681 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
683 inlDataCon, inrDataCon :: DataCon
684 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
685 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
687 genUnitTyCon :: TyCon -- The "1" type constructor for generics
688 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
690 genUnitDataCon :: DataCon
691 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon