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,
35 falseDataCon, falseDataConId,
60 unitTyCon, unitDataConId, pairTyCon,
61 unboxedSingletonTyCon, unboxedSingletonDataCon,
62 unboxedPairTyCon, unboxedPairDataCon,
65 genUnitTyCon, genUnitDataCon,
66 plusTyCon, inrDataCon, inlDataCon,
67 crossTyCon, crossDataCon,
71 trueDataCon, trueDataConId,
78 isFFIArgumentTy, -- :: DynFlags -> Safety -> Type -> Bool
79 isFFIImportResultTy, -- :: DynFlags -> Type -> Bool
80 isFFIExportResultTy, -- :: Type -> Bool
81 isFFIExternalTy, -- :: Type -> Bool
82 isFFIDynArgumentTy, -- :: Type -> Bool
83 isFFIDynResultTy, -- :: Type -> Bool
84 isFFILabelTy, -- :: Type -> Bool
85 isAddrTy, -- :: Type -> Bool
86 isForeignPtrTy -- :: Type -> Bool
90 #include "HsVersions.h"
92 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
93 import {-# SOURCE #-} Generics( mkTyConGenInfo )
100 import ForeignCall ( Safety, playSafe )
101 import Constants ( mAX_TUPLE_SIZE )
102 import Module ( mkPrelModule )
103 import Name ( Name, nameRdrName, nameUnique, nameOccName,
104 nameModule, mkWiredInName )
105 import OccName ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
106 import RdrName ( rdrNameOcc )
107 import DataCon ( DataCon, mkDataCon, dataConId )
108 import Demand ( StrictnessMark(..) )
109 import Var ( TyVar, tyVarKind )
110 import TyCon ( TyCon, AlgTyConFlavour(..), tyConDataCons,
111 mkTupleTyCon, isUnLiftedTyCon, mkAlgTyCon
114 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
116 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTys,
117 mkArrowKinds, liftedTypeKind, unliftedTypeKind,
118 splitTyConApp_maybe, repType,
120 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
125 alpha_tyvar = [alphaTyVar]
127 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
131 %************************************************************************
133 \subsection{Wired in type constructors}
135 %************************************************************************
138 wiredInTyCons :: [TyCon]
139 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
141 data_tycons = genericTyCons ++
155 genericTyCons :: [TyCon]
156 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
159 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..mAX_TUPLE_SIZE] ]
160 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..mAX_TUPLE_SIZE] ]
164 %************************************************************************
166 \subsection{mkWiredInTyCon}
168 %************************************************************************
171 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
172 pcRecDataTyCon = pcTyCon DataTyCon Recursive
174 pcTyCon new_or_data is_rec name tyvars argvrcs cons
177 tycon = mkAlgTyCon name kind
183 [] -- No record selectors
188 mod = nameModule name
189 kind = mkArrowKinds (map tyVarKind tyvars) liftedTypeKind
190 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
192 -- We generate names for the generic to/from Ids by incrementing
193 -- the TyCon unique. So each Prelude tycon needs 3 slots, one
194 -- for itself and two more for the generic Ids.
195 mk_tc_gen_info mod tc_uniq tc_name tycon
196 = mkTyConGenInfo tycon [name1, name2]
198 tc_occ_name = nameOccName tc_name
199 occ_name1 = mkGenOcc1 tc_occ_name
200 occ_name2 = mkGenOcc2 tc_occ_name
201 fn1_key = incrUnique tc_uniq
202 fn2_key = incrUnique fn1_key
203 name1 = mkWiredInName mod occ_name1 fn1_key
204 name2 = mkWiredInName mod occ_name2 fn2_key
206 pcDataCon :: Name -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
207 -- The unique is the first of two free uniques;
208 -- the first is used for the datacon itself and the worker;
209 -- the second is used for the wrapper.
211 pcDataCon name tyvars context arg_tys tycon
214 data_con = mkDataCon name
215 [ NotMarkedStrict | a <- arg_tys ]
216 [ {- no labelled fields -} ]
217 tyvars context [] [] arg_tys tycon work_id wrap_id
219 wrap_rdr = nameRdrName name
220 wrap_occ = rdrNameOcc wrap_rdr
222 mod = nameModule name
223 wrap_id = mkDataConWrapId data_con
225 work_occ = mkWorkerOcc wrap_occ
226 work_key = incrUnique (nameUnique name)
227 work_name = mkWiredInName mod work_occ work_key
228 work_id = mkDataConId work_name data_con
232 %************************************************************************
234 \subsection[TysWiredIn-tuples]{The tuple types}
236 %************************************************************************
239 tupleTyCon :: Boxity -> Arity -> TyCon
240 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
241 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
242 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
244 tupleCon :: Boxity -> Arity -> DataCon
245 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
246 tupleCon Boxed i = snd (boxedTupleArr ! i)
247 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
249 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
250 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
251 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
253 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
254 mk_tuple boxity arity = (tycon, tuple_con)
256 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
257 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
258 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
259 res_kind | isBoxed boxity = liftedTypeKind
260 | otherwise = unliftedTypeKind
262 tyvars | isBoxed boxity = take arity alphaTyVars
263 | otherwise = take arity openAlphaTyVars
265 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
266 tyvar_tys = mkTyVarTys tyvars
267 (mod_name, name_str) = mkTupNameStr boxity arity
268 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
269 tc_uniq = mkTupleTyConUnique boxity arity
270 dc_uniq = mkTupleDataConUnique boxity arity
271 mod = mkPrelModule mod_name
272 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
274 unitTyCon = tupleTyCon Boxed 0
275 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
277 pairTyCon = tupleTyCon Boxed 2
279 unboxedSingletonTyCon = tupleTyCon Unboxed 1
280 unboxedSingletonDataCon = tupleCon Unboxed 1
282 unboxedPairTyCon = tupleTyCon Unboxed 2
283 unboxedPairDataCon = tupleCon Unboxed 2
286 %************************************************************************
288 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
290 %************************************************************************
293 -- The Void type is represented as a data type with no constructors
294 -- It's a built in type (i.e. there's no way to define it in Haskell;
295 -- the nearest would be
297 -- data Void = -- No constructors!
299 -- ) It's lifted; there is only one value of this
300 -- type, namely "void", whose semantics is just bottom.
302 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
309 charTy = mkTyConTy charTyCon
311 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
312 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
314 stringTy = mkListTy charTy -- convenience only
318 intTy = mkTyConTy intTyCon
320 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
321 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
323 isIntTy :: Type -> Bool
324 isIntTy = isTyCon intTyConKey
329 wordTy = mkTyConTy wordTyCon
331 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
332 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
336 addrTy = mkTyConTy addrTyCon
338 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
339 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
341 isAddrTy :: Type -> Bool
342 isAddrTy = isTyCon addrTyConKey
346 ptrTy = mkTyConTy ptrTyCon
348 ptrTyCon = pcNonRecDataTyCon ptrTyConName alpha_tyvar [(True,False)] [ptrDataCon]
349 ptrDataCon = pcDataCon ptrDataConName alpha_tyvar [] [addrPrimTy] ptrTyCon
353 funPtrTy = mkTyConTy funPtrTyCon
355 funPtrTyCon = pcNonRecDataTyCon funPtrTyConName alpha_tyvar [(True,False)] [funPtrDataCon]
356 funPtrDataCon = pcDataCon funPtrDataConName alpha_tyvar [] [addrPrimTy] funPtrTyCon
360 floatTy = mkTyConTy floatTyCon
362 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
363 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
365 isFloatTy :: Type -> Bool
366 isFloatTy = isTyCon floatTyConKey
370 doubleTy = mkTyConTy doubleTyCon
372 isDoubleTy :: Type -> Bool
373 isDoubleTy = isTyCon doubleTyConKey
375 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
376 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
381 = pcNonRecDataTyCon stablePtrTyConName
382 alpha_tyvar [(True,False)] [stablePtrDataCon]
385 = pcDataCon stablePtrDataConName
386 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
391 = pcNonRecDataTyCon foreignObjTyConName
392 [] [] [foreignObjDataCon]
395 = pcDataCon foreignObjDataConName
396 [] [] [foreignObjPrimTy] foreignObjTyCon
401 = pcNonRecDataTyCon foreignPtrTyConName
402 alpha_tyvar [(True,False)] [foreignPtrDataCon]
405 = pcDataCon foreignPtrDataConName
406 alpha_tyvar [] [foreignObjPrimTy] foreignPtrTyCon
408 isForeignPtrTy :: Type -> Bool
409 isForeignPtrTy = isTyCon foreignPtrTyConKey
412 %************************************************************************
414 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
416 %************************************************************************
418 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
421 integerTy = mkTyConTy integerTyCon
423 integerTyCon = pcNonRecDataTyCon integerTyConName
424 [] [] [smallIntegerDataCon, largeIntegerDataCon]
426 smallIntegerDataCon = pcDataCon smallIntegerDataConName
427 [] [] [intPrimTy] integerTyCon
428 largeIntegerDataCon = pcDataCon largeIntegerDataConName
429 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
432 isIntegerTy :: Type -> Bool
433 isIntegerTy = isTyCon integerTyConKey
437 %************************************************************************
439 \subsection[TysWiredIn-ext-type]{External types}
441 %************************************************************************
443 The compiler's foreign function interface supports the passing of a
444 restricted set of types as arguments and results (the restricting factor
448 isFFIArgumentTy :: DynFlags -> Safety -> Type -> Bool
449 -- Checks for valid argument type for a 'foreign import'
450 isFFIArgumentTy dflags safety ty
451 = checkRepTyCon (legalOutgoingTyCon dflags safety) ty
453 isFFIExternalTy :: Type -> Bool
454 -- Types that are allowed as arguments of a 'foreign export'
455 isFFIExternalTy ty = checkRepTyCon legalFEArgTyCon ty
457 isFFIImportResultTy :: DynFlags -> Type -> Bool
458 isFFIImportResultTy dflags ty
459 = checkRepTyCon (legalFIResultTyCon dflags) ty
461 isFFIExportResultTy :: Type -> Bool
462 isFFIExportResultTy ty = checkRepTyCon legalFEResultTyCon ty
464 isFFIDynArgumentTy :: Type -> Bool
465 -- The argument type of a foreign import dynamic must be Ptr, FunPtr, Addr,
466 -- or a newtype of either.
467 isFFIDynArgumentTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
469 isFFIDynResultTy :: Type -> Bool
470 -- The result type of a foreign export dynamic must be Ptr, FunPtr, Addr,
471 -- or a newtype of either.
472 isFFIDynResultTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
474 isFFILabelTy :: Type -> Bool
475 -- The type of a foreign label must be Ptr, FunPtr, Addr,
476 -- or a newtype of either.
477 isFFILabelTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
479 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
480 -- look through newtypes
481 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
483 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
484 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
485 Just (tycon, _) -> check_tc tycon
488 isTyCon :: Unique -> Type -> Bool
489 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
492 ----------------------------------------------
493 These chaps do the work; they are not exported
494 ----------------------------------------------
497 legalFEArgTyCon :: TyCon -> Bool
498 -- It's illegal to return foreign objects and (mutable)
499 -- bytearrays from a _ccall_ / foreign declaration
500 -- (or be passed them as arguments in foreign exported functions).
502 | getUnique tc `elem` [ foreignObjTyConKey, foreignPtrTyConKey,
503 byteArrayTyConKey, mutableByteArrayTyConKey ]
505 -- It's also illegal to make foreign exports that take unboxed
506 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
508 = boxedMarshalableTyCon tc
510 legalFIResultTyCon :: DynFlags -> TyCon -> Bool
511 legalFIResultTyCon dflags tc
512 | getUnique tc `elem`
513 [ foreignObjTyConKey, foreignPtrTyConKey,
514 byteArrayTyConKey, mutableByteArrayTyConKey ] = False
515 | tc == unitTyCon = True
516 | otherwise = marshalableTyCon dflags tc
518 legalFEResultTyCon :: TyCon -> Bool
519 legalFEResultTyCon tc
520 | getUnique tc `elem`
521 [ foreignObjTyConKey, foreignPtrTyConKey,
522 byteArrayTyConKey, mutableByteArrayTyConKey ] = False
523 | tc == unitTyCon = True
524 | otherwise = boxedMarshalableTyCon tc
526 legalOutgoingTyCon :: DynFlags -> Safety -> TyCon -> Bool
527 -- Checks validity of types going from Haskell -> external world
528 legalOutgoingTyCon dflags safety tc
529 | playSafe safety && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
532 = marshalableTyCon dflags tc
534 marshalableTyCon dflags tc
535 = (dopt Opt_GlasgowExts dflags && isUnLiftedTyCon tc)
536 || boxedMarshalableTyCon tc
538 boxedMarshalableTyCon tc
539 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey
540 , int32TyConKey, int64TyConKey
541 , wordTyConKey, word8TyConKey, word16TyConKey
542 , word32TyConKey, word64TyConKey
543 , floatTyConKey, doubleTyConKey
544 , addrTyConKey, ptrTyConKey, funPtrTyConKey
545 , charTyConKey, foreignObjTyConKey
548 , byteArrayTyConKey, mutableByteArrayTyConKey
554 %************************************************************************
556 \subsection[TysWiredIn-Bool]{The @Bool@ type}
558 %************************************************************************
560 An ordinary enumeration type, but deeply wired in. There are no
561 magical operations on @Bool@ (just the regular Prelude code).
563 {\em BEGIN IDLE SPECULATION BY SIMON}
565 This is not the only way to encode @Bool@. A more obvious coding makes
566 @Bool@ just a boxed up version of @Bool#@, like this:
569 data Bool = MkBool Bool#
572 Unfortunately, this doesn't correspond to what the Report says @Bool@
573 looks like! Furthermore, we get slightly less efficient code (I
574 think) with this coding. @gtInt@ would look like this:
577 gtInt :: Int -> Int -> Bool
578 gtInt x y = case x of I# x# ->
580 case (gtIntPrim x# y#) of
584 Notice that the result of the @gtIntPrim@ comparison has to be turned
585 into an integer (here called @b#@), and returned in a @MkBool@ box.
587 The @if@ expression would compile to this:
590 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
593 I think this code is a little less efficient than the previous code,
594 but I'm not certain. At all events, corresponding with the Report is
595 important. The interesting thing is that the language is expressive
596 enough to describe more than one alternative; and that a type doesn't
597 necessarily need to be a straightforwardly boxed version of its
598 primitive counterpart.
600 {\em END IDLE SPECULATION BY SIMON}
603 boolTy = mkTyConTy boolTyCon
605 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
606 [] [] [falseDataCon, trueDataCon]
608 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
609 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
611 falseDataConId = dataConId falseDataCon
612 trueDataConId = dataConId trueDataCon
615 %************************************************************************
617 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
619 %************************************************************************
621 Special syntax, deeply wired in, but otherwise an ordinary algebraic
624 data [] a = [] | a : (List a)
626 data (,) a b = (,,) a b
631 mkListTy :: Type -> Type
632 mkListTy ty = mkTyConApp listTyCon [ty]
634 listTyCon = pcRecDataTyCon listTyConName
635 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
637 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
638 consDataCon = pcDataCon consDataConName
639 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
640 -- Interesting: polymorphic recursion would help here.
641 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
642 -- gets the over-specific type (Type -> Type)
645 %************************************************************************
647 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
649 %************************************************************************
651 The tuple types are definitely magic, because they form an infinite
656 They have a special family of type constructors, of type @TyCon@
657 These contain the tycon arity, but don't require a Unique.
660 They have a special family of constructors, of type
661 @Id@. Again these contain their arity but don't need a Unique.
664 There should be a magic way of generating the info tables and
665 entry code for all tuples.
667 But at the moment we just compile a Haskell source
668 file\srcloc{lib/prelude/...} containing declarations like:
671 data Tuple2 a b = Tup2 a b
672 data Tuple3 a b c = Tup3 a b c
673 data Tuple4 a b c d = Tup4 a b c d
676 The print-names associated with the magic @Id@s for tuple constructors
677 ``just happen'' to be the same as those generated by these
681 The instance environment should have a magic way to know
682 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
683 so on. \ToDo{Not implemented yet.}
686 There should also be a way to generate the appropriate code for each
687 of these instances, but (like the info tables and entry code) it is
688 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
692 mkTupleTy :: Boxity -> Int -> [Type] -> Type
693 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
695 unitTy = mkTupleTy Boxed 0 []
698 %************************************************************************
700 \subsection{Wired In Type Constructors for Representation Types}
702 %************************************************************************
704 The following code defines the wired in datatypes cross, plus, unit
705 and c_of needed for the generic methods.
707 Ok, so the basic story is that for each type constructor I need to
708 create 2 things - a TyCon and a DataCon and then we are basically
709 ok. There are going to be no arguments passed to these functions
710 because -well- there is nothing to pass to these functions.
714 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
716 crossDataCon :: DataCon
717 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
720 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
722 inlDataCon, inrDataCon :: DataCon
723 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
724 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
726 genUnitTyCon :: TyCon -- The "1" type constructor for generics
727 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
729 genUnitDataCon :: DataCon
730 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon