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,
34 falseDataCon, falseDataConId,
56 unitTyCon, unitDataConId, pairTyCon,
57 unboxedSingletonTyCon, unboxedSingletonDataCon,
58 unboxedPairTyCon, unboxedPairDataCon,
61 genUnitTyCon, genUnitDataCon,
62 plusTyCon, inrDataCon, inlDataCon,
63 crossTyCon, crossDataCon,
67 trueDataCon, trueDataConId,
74 isFFIArgumentTy, -- :: DynFlags -> Safety -> Type -> Bool
75 isFFIImportResultTy, -- :: DynFlags -> Type -> Bool
76 isFFIExportResultTy, -- :: Type -> Bool
77 isFFIExternalTy, -- :: Type -> Bool
78 isFFIDynArgumentTy, -- :: Type -> Bool
79 isFFIDynResultTy, -- :: Type -> Bool
80 isFFILabelTy, -- :: Type -> Bool
83 #include "HsVersions.h"
85 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
86 import {-# SOURCE #-} Generics( mkTyConGenInfo )
93 import ForeignCall ( Safety, playSafe )
94 import Constants ( mAX_TUPLE_SIZE )
95 import Module ( mkPrelModule )
96 import Name ( Name, nameRdrName, nameUnique, nameOccName,
97 nameModule, mkWiredInName )
98 import OccName ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
99 import RdrName ( rdrNameOcc )
100 import DataCon ( DataCon, mkDataCon, dataConId )
101 import Var ( TyVar, tyVarKind )
102 import TyCon ( TyCon, AlgTyConFlavour(..), tyConDataCons,
103 mkTupleTyCon, isUnLiftedTyCon, mkAlgTyCon
106 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed, StrictnessMark(..) )
108 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTys,
109 mkArrowKinds, liftedTypeKind, unliftedTypeKind,
112 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
117 alpha_tyvar = [alphaTyVar]
119 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
123 %************************************************************************
125 \subsection{Wired in type constructors}
127 %************************************************************************
130 wiredInTyCons :: [TyCon]
131 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
133 data_tycons = genericTyCons ++
147 genericTyCons :: [TyCon]
148 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
151 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..mAX_TUPLE_SIZE] ]
152 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..mAX_TUPLE_SIZE] ]
156 %************************************************************************
158 \subsection{mkWiredInTyCon}
160 %************************************************************************
163 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
164 pcRecDataTyCon = pcTyCon DataTyCon Recursive
166 pcTyCon new_or_data is_rec name tyvars argvrcs cons
169 tycon = mkAlgTyCon name kind
175 [] -- No record selectors
180 mod = nameModule name
181 kind = mkArrowKinds (map tyVarKind tyvars) liftedTypeKind
182 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
184 -- We generate names for the generic to/from Ids by incrementing
185 -- the TyCon unique. So each Prelude tycon needs 3 slots, one
186 -- for itself and two more for the generic Ids.
187 mk_tc_gen_info mod tc_uniq tc_name tycon
188 = mkTyConGenInfo tycon [name1, name2]
190 tc_occ_name = nameOccName tc_name
191 occ_name1 = mkGenOcc1 tc_occ_name
192 occ_name2 = mkGenOcc2 tc_occ_name
193 fn1_key = incrUnique tc_uniq
194 fn2_key = incrUnique fn1_key
195 name1 = mkWiredInName mod occ_name1 fn1_key
196 name2 = mkWiredInName mod occ_name2 fn2_key
198 pcDataCon :: Name -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
199 -- The unique is the first of two free uniques;
200 -- the first is used for the datacon itself and the worker;
201 -- the second is used for the wrapper.
203 pcDataCon name tyvars context arg_tys tycon
206 data_con = mkDataCon name
207 [ NotMarkedStrict | a <- arg_tys ]
208 [ {- no labelled fields -} ]
209 tyvars context [] [] arg_tys tycon work_id wrap_id
211 wrap_rdr = nameRdrName name
212 wrap_occ = rdrNameOcc wrap_rdr
214 mod = nameModule name
215 wrap_id = mkDataConWrapId data_con
217 work_occ = mkWorkerOcc wrap_occ
218 work_key = incrUnique (nameUnique name)
219 work_name = mkWiredInName mod work_occ work_key
220 work_id = mkDataConId work_name data_con
224 %************************************************************************
226 \subsection[TysWiredIn-tuples]{The tuple types}
228 %************************************************************************
231 tupleTyCon :: Boxity -> Arity -> TyCon
232 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
233 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
234 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
236 tupleCon :: Boxity -> Arity -> DataCon
237 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
238 tupleCon Boxed i = snd (boxedTupleArr ! i)
239 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
241 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
242 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
243 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
245 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
246 mk_tuple boxity arity = (tycon, tuple_con)
248 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
249 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
250 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
251 res_kind | isBoxed boxity = liftedTypeKind
252 | otherwise = unliftedTypeKind
254 tyvars | isBoxed boxity = take arity alphaTyVars
255 | otherwise = take arity openAlphaTyVars
257 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
258 tyvar_tys = mkTyVarTys tyvars
259 (mod_name, name_str) = mkTupNameStr boxity arity
260 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
261 tc_uniq = mkTupleTyConUnique boxity arity
262 dc_uniq = mkTupleDataConUnique boxity arity
263 mod = mkPrelModule mod_name
264 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
266 unitTyCon = tupleTyCon Boxed 0
267 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
269 pairTyCon = tupleTyCon Boxed 2
271 unboxedSingletonTyCon = tupleTyCon Unboxed 1
272 unboxedSingletonDataCon = tupleCon Unboxed 1
274 unboxedPairTyCon = tupleTyCon Unboxed 2
275 unboxedPairDataCon = tupleCon Unboxed 2
278 %************************************************************************
280 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
282 %************************************************************************
285 -- The Void type is represented as a data type with no constructors
286 -- It's a built in type (i.e. there's no way to define it in Haskell;
287 -- the nearest would be
289 -- data Void = -- No constructors!
291 -- ) It's lifted; there is only one value of this
292 -- type, namely "void", whose semantics is just bottom.
294 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
301 charTy = mkTyConTy charTyCon
303 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
304 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
306 stringTy = mkListTy charTy -- convenience only
310 intTy = mkTyConTy intTyCon
312 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
313 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
317 wordTy = mkTyConTy wordTyCon
319 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
320 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
324 addrTy = mkTyConTy addrTyCon
326 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
327 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
331 ptrTy = mkTyConTy ptrTyCon
333 ptrTyCon = pcNonRecDataTyCon ptrTyConName alpha_tyvar [(True,False)] [ptrDataCon]
334 ptrDataCon = pcDataCon ptrDataConName alpha_tyvar [] [addrPrimTy] ptrTyCon
338 funPtrTy = mkTyConTy funPtrTyCon
340 funPtrTyCon = pcNonRecDataTyCon funPtrTyConName alpha_tyvar [(True,False)] [funPtrDataCon]
341 funPtrDataCon = pcDataCon funPtrDataConName alpha_tyvar [] [addrPrimTy] funPtrTyCon
345 floatTy = mkTyConTy floatTyCon
347 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
348 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
352 doubleTy = mkTyConTy doubleTyCon
354 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
355 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
360 = pcNonRecDataTyCon stablePtrTyConName
361 alpha_tyvar [(True,False)] [stablePtrDataCon]
364 = pcDataCon stablePtrDataConName
365 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
370 = pcNonRecDataTyCon foreignObjTyConName
371 [] [] [foreignObjDataCon]
374 = pcDataCon foreignObjDataConName
375 [] [] [foreignObjPrimTy] foreignObjTyCon
380 = pcNonRecDataTyCon foreignPtrTyConName
381 alpha_tyvar [(True,False)] [foreignPtrDataCon]
384 = pcDataCon foreignPtrDataConName
385 alpha_tyvar [] [foreignObjPrimTy] foreignPtrTyCon
388 %************************************************************************
390 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
392 %************************************************************************
394 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
397 integerTy = mkTyConTy integerTyCon
399 integerTyCon = pcNonRecDataTyCon integerTyConName
400 [] [] [smallIntegerDataCon, largeIntegerDataCon]
402 smallIntegerDataCon = pcDataCon smallIntegerDataConName
403 [] [] [intPrimTy] integerTyCon
404 largeIntegerDataCon = pcDataCon largeIntegerDataConName
405 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
409 %************************************************************************
411 \subsection[TysWiredIn-ext-type]{External types}
413 %************************************************************************
415 The compiler's foreign function interface supports the passing of a
416 restricted set of types as arguments and results (the restricting factor
420 isFFIArgumentTy :: DynFlags -> Safety -> Type -> Bool
421 -- Checks for valid argument type for a 'foreign import'
422 isFFIArgumentTy dflags safety ty
423 = checkRepTyCon (legalOutgoingTyCon dflags safety) ty
425 isFFIExternalTy :: Type -> Bool
426 -- Types that are allowed as arguments of a 'foreign export'
427 isFFIExternalTy ty = checkRepTyCon legalFEArgTyCon ty
429 isFFIImportResultTy :: DynFlags -> Type -> Bool
430 isFFIImportResultTy dflags ty
431 = checkRepTyCon (legalFIResultTyCon dflags) ty
433 isFFIExportResultTy :: Type -> Bool
434 isFFIExportResultTy ty = checkRepTyCon legalFEResultTyCon ty
436 isFFIDynArgumentTy :: Type -> Bool
437 -- The argument type of a foreign import dynamic must be Ptr, FunPtr, Addr,
438 -- or a newtype of either.
439 isFFIDynArgumentTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
441 isFFIDynResultTy :: Type -> Bool
442 -- The result type of a foreign export dynamic must be Ptr, FunPtr, Addr,
443 -- or a newtype of either.
444 isFFIDynResultTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
446 isFFILabelTy :: Type -> Bool
447 -- The type of a foreign label must be Ptr, FunPtr, Addr,
448 -- or a newtype of either.
449 isFFILabelTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
451 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
452 -- Look through newtypes
453 checkRepTyCon check_tc ty = case splitTyConApp_maybe ty of
454 Just (tycon, _) -> check_tc tycon
458 ----------------------------------------------
459 These chaps do the work; they are not exported
460 ----------------------------------------------
463 legalFEArgTyCon :: TyCon -> Bool
464 -- It's illegal to return foreign objects and (mutable)
465 -- bytearrays from a _ccall_ / foreign declaration
466 -- (or be passed them as arguments in foreign exported functions).
468 | getUnique tc `elem` [ foreignObjTyConKey, foreignPtrTyConKey,
469 byteArrayTyConKey, mutableByteArrayTyConKey ]
471 -- It's also illegal to make foreign exports that take unboxed
472 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
474 = boxedMarshalableTyCon tc
476 legalFIResultTyCon :: DynFlags -> TyCon -> Bool
477 legalFIResultTyCon dflags tc
478 | getUnique tc `elem`
479 [ foreignObjTyConKey, foreignPtrTyConKey,
480 byteArrayTyConKey, mutableByteArrayTyConKey ] = False
481 | tc == unitTyCon = True
482 | otherwise = marshalableTyCon dflags tc
484 legalFEResultTyCon :: TyCon -> Bool
485 legalFEResultTyCon tc
486 | getUnique tc `elem`
487 [ foreignObjTyConKey, foreignPtrTyConKey,
488 byteArrayTyConKey, mutableByteArrayTyConKey ] = False
489 | tc == unitTyCon = True
490 | otherwise = boxedMarshalableTyCon tc
492 legalOutgoingTyCon :: DynFlags -> Safety -> TyCon -> Bool
493 -- Checks validity of types going from Haskell -> external world
494 legalOutgoingTyCon dflags safety tc
495 | playSafe safety && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
498 = marshalableTyCon dflags tc
500 marshalableTyCon dflags tc
501 = (dopt Opt_GlasgowExts dflags && isUnLiftedTyCon tc)
502 || boxedMarshalableTyCon tc
504 boxedMarshalableTyCon tc
505 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey
506 , int32TyConKey, int64TyConKey
507 , wordTyConKey, word8TyConKey, word16TyConKey
508 , word32TyConKey, word64TyConKey
509 , floatTyConKey, doubleTyConKey
510 , addrTyConKey, ptrTyConKey, funPtrTyConKey
511 , charTyConKey, foreignObjTyConKey
514 , byteArrayTyConKey, mutableByteArrayTyConKey
520 %************************************************************************
522 \subsection[TysWiredIn-Bool]{The @Bool@ type}
524 %************************************************************************
526 An ordinary enumeration type, but deeply wired in. There are no
527 magical operations on @Bool@ (just the regular Prelude code).
529 {\em BEGIN IDLE SPECULATION BY SIMON}
531 This is not the only way to encode @Bool@. A more obvious coding makes
532 @Bool@ just a boxed up version of @Bool#@, like this:
535 data Bool = MkBool Bool#
538 Unfortunately, this doesn't correspond to what the Report says @Bool@
539 looks like! Furthermore, we get slightly less efficient code (I
540 think) with this coding. @gtInt@ would look like this:
543 gtInt :: Int -> Int -> Bool
544 gtInt x y = case x of I# x# ->
546 case (gtIntPrim x# y#) of
550 Notice that the result of the @gtIntPrim@ comparison has to be turned
551 into an integer (here called @b#@), and returned in a @MkBool@ box.
553 The @if@ expression would compile to this:
556 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
559 I think this code is a little less efficient than the previous code,
560 but I'm not certain. At all events, corresponding with the Report is
561 important. The interesting thing is that the language is expressive
562 enough to describe more than one alternative; and that a type doesn't
563 necessarily need to be a straightforwardly boxed version of its
564 primitive counterpart.
566 {\em END IDLE SPECULATION BY SIMON}
569 boolTy = mkTyConTy boolTyCon
571 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
572 [] [] [falseDataCon, trueDataCon]
574 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
575 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
577 falseDataConId = dataConId falseDataCon
578 trueDataConId = dataConId trueDataCon
581 %************************************************************************
583 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
585 %************************************************************************
587 Special syntax, deeply wired in, but otherwise an ordinary algebraic
590 data [] a = [] | a : (List a)
592 data (,) a b = (,,) a b
597 mkListTy :: Type -> Type
598 mkListTy ty = mkTyConApp listTyCon [ty]
600 listTyCon = pcRecDataTyCon listTyConName
601 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
603 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
604 consDataCon = pcDataCon consDataConName
605 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
606 -- Interesting: polymorphic recursion would help here.
607 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
608 -- gets the over-specific type (Type -> Type)
611 %************************************************************************
613 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
615 %************************************************************************
617 The tuple types are definitely magic, because they form an infinite
622 They have a special family of type constructors, of type @TyCon@
623 These contain the tycon arity, but don't require a Unique.
626 They have a special family of constructors, of type
627 @Id@. Again these contain their arity but don't need a Unique.
630 There should be a magic way of generating the info tables and
631 entry code for all tuples.
633 But at the moment we just compile a Haskell source
634 file\srcloc{lib/prelude/...} containing declarations like:
637 data Tuple2 a b = Tup2 a b
638 data Tuple3 a b c = Tup3 a b c
639 data Tuple4 a b c d = Tup4 a b c d
642 The print-names associated with the magic @Id@s for tuple constructors
643 ``just happen'' to be the same as those generated by these
647 The instance environment should have a magic way to know
648 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
649 so on. \ToDo{Not implemented yet.}
652 There should also be a way to generate the appropriate code for each
653 of these instances, but (like the info tables and entry code) it is
654 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
658 mkTupleTy :: Boxity -> Int -> [Type] -> Type
659 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
661 unitTy = mkTupleTy Boxed 0 []
664 %************************************************************************
666 \subsection{Wired In Type Constructors for Representation Types}
668 %************************************************************************
670 The following code defines the wired in datatypes cross, plus, unit
671 and c_of needed for the generic methods.
673 Ok, so the basic story is that for each type constructor I need to
674 create 2 things - a TyCon and a DataCon and then we are basically
675 ok. There are going to be no arguments passed to these functions
676 because -well- there is nothing to pass to these functions.
680 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
682 crossDataCon :: DataCon
683 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
686 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
688 inlDataCon, inrDataCon :: DataCon
689 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
690 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
692 genUnitTyCon :: TyCon -- The "1" type constructor for generics
693 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
695 genUnitDataCon :: DataCon
696 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon