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 Demand ( StrictnessMark(..) )
102 import Var ( TyVar, tyVarKind )
103 import TyCon ( TyCon, AlgTyConFlavour(..), tyConDataCons,
104 mkTupleTyCon, isUnLiftedTyCon, mkAlgTyCon
107 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
109 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTys,
110 mkArrowKinds, liftedTypeKind, unliftedTypeKind,
113 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
118 alpha_tyvar = [alphaTyVar]
120 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
124 %************************************************************************
126 \subsection{Wired in type constructors}
128 %************************************************************************
131 wiredInTyCons :: [TyCon]
132 wiredInTyCons = data_tycons ++ tuple_tycons ++ unboxed_tuple_tycons
134 data_tycons = genericTyCons ++
148 genericTyCons :: [TyCon]
149 genericTyCons = [ plusTyCon, crossTyCon, genUnitTyCon ]
152 tuple_tycons = unitTyCon : [tupleTyCon Boxed i | i <- [2..mAX_TUPLE_SIZE] ]
153 unboxed_tuple_tycons = [tupleTyCon Unboxed i | i <- [1..mAX_TUPLE_SIZE] ]
157 %************************************************************************
159 \subsection{mkWiredInTyCon}
161 %************************************************************************
164 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
165 pcRecDataTyCon = pcTyCon DataTyCon Recursive
167 pcTyCon new_or_data is_rec name tyvars argvrcs cons
170 tycon = mkAlgTyCon name kind
176 [] -- No record selectors
181 mod = nameModule name
182 kind = mkArrowKinds (map tyVarKind tyvars) liftedTypeKind
183 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
185 -- We generate names for the generic to/from Ids by incrementing
186 -- the TyCon unique. So each Prelude tycon needs 3 slots, one
187 -- for itself and two more for the generic Ids.
188 mk_tc_gen_info mod tc_uniq tc_name tycon
189 = mkTyConGenInfo tycon [name1, name2]
191 tc_occ_name = nameOccName tc_name
192 occ_name1 = mkGenOcc1 tc_occ_name
193 occ_name2 = mkGenOcc2 tc_occ_name
194 fn1_key = incrUnique tc_uniq
195 fn2_key = incrUnique fn1_key
196 name1 = mkWiredInName mod occ_name1 fn1_key
197 name2 = mkWiredInName mod occ_name2 fn2_key
199 pcDataCon :: Name -> [TyVar] -> ThetaType -> [TauType] -> TyCon -> DataCon
200 -- The unique is the first of two free uniques;
201 -- the first is used for the datacon itself and the worker;
202 -- the second is used for the wrapper.
204 pcDataCon name tyvars context arg_tys tycon
207 data_con = mkDataCon name
208 [ NotMarkedStrict | a <- arg_tys ]
209 [ {- no labelled fields -} ]
210 tyvars context [] [] arg_tys tycon work_id wrap_id
212 wrap_rdr = nameRdrName name
213 wrap_occ = rdrNameOcc wrap_rdr
215 mod = nameModule name
216 wrap_id = mkDataConWrapId data_con
218 work_occ = mkWorkerOcc wrap_occ
219 work_key = incrUnique (nameUnique name)
220 work_name = mkWiredInName mod work_occ work_key
221 work_id = mkDataConId work_name data_con
225 %************************************************************************
227 \subsection[TysWiredIn-tuples]{The tuple types}
229 %************************************************************************
232 tupleTyCon :: Boxity -> Arity -> TyCon
233 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
234 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
235 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
237 tupleCon :: Boxity -> Arity -> DataCon
238 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
239 tupleCon Boxed i = snd (boxedTupleArr ! i)
240 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
242 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
243 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
244 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
246 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
247 mk_tuple boxity arity = (tycon, tuple_con)
249 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
250 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
251 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
252 res_kind | isBoxed boxity = liftedTypeKind
253 | otherwise = unliftedTypeKind
255 tyvars | isBoxed boxity = take arity alphaTyVars
256 | otherwise = take arity openAlphaTyVars
258 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
259 tyvar_tys = mkTyVarTys tyvars
260 (mod_name, name_str) = mkTupNameStr boxity arity
261 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
262 tc_uniq = mkTupleTyConUnique boxity arity
263 dc_uniq = mkTupleDataConUnique boxity arity
264 mod = mkPrelModule mod_name
265 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
267 unitTyCon = tupleTyCon Boxed 0
268 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
270 pairTyCon = tupleTyCon Boxed 2
272 unboxedSingletonTyCon = tupleTyCon Unboxed 1
273 unboxedSingletonDataCon = tupleCon Unboxed 1
275 unboxedPairTyCon = tupleTyCon Unboxed 2
276 unboxedPairDataCon = tupleCon Unboxed 2
279 %************************************************************************
281 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
283 %************************************************************************
286 -- The Void type is represented as a data type with no constructors
287 -- It's a built in type (i.e. there's no way to define it in Haskell;
288 -- the nearest would be
290 -- data Void = -- No constructors!
292 -- ) It's lifted; there is only one value of this
293 -- type, namely "void", whose semantics is just bottom.
295 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
302 charTy = mkTyConTy charTyCon
304 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
305 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
307 stringTy = mkListTy charTy -- convenience only
311 intTy = mkTyConTy intTyCon
313 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
314 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
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
332 ptrTy = mkTyConTy ptrTyCon
334 ptrTyCon = pcNonRecDataTyCon ptrTyConName alpha_tyvar [(True,False)] [ptrDataCon]
335 ptrDataCon = pcDataCon ptrDataConName alpha_tyvar [] [addrPrimTy] ptrTyCon
339 funPtrTy = mkTyConTy funPtrTyCon
341 funPtrTyCon = pcNonRecDataTyCon funPtrTyConName alpha_tyvar [(True,False)] [funPtrDataCon]
342 funPtrDataCon = pcDataCon funPtrDataConName alpha_tyvar [] [addrPrimTy] funPtrTyCon
346 floatTy = mkTyConTy floatTyCon
348 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
349 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
353 doubleTy = mkTyConTy doubleTyCon
355 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
356 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
361 = pcNonRecDataTyCon stablePtrTyConName
362 alpha_tyvar [(True,False)] [stablePtrDataCon]
365 = pcDataCon stablePtrDataConName
366 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
371 = pcNonRecDataTyCon foreignObjTyConName
372 [] [] [foreignObjDataCon]
375 = pcDataCon foreignObjDataConName
376 [] [] [foreignObjPrimTy] foreignObjTyCon
381 = pcNonRecDataTyCon foreignPtrTyConName
382 alpha_tyvar [(True,False)] [foreignPtrDataCon]
385 = pcDataCon foreignPtrDataConName
386 alpha_tyvar [] [foreignObjPrimTy] foreignPtrTyCon
389 %************************************************************************
391 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
393 %************************************************************************
395 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
398 integerTy = mkTyConTy integerTyCon
400 integerTyCon = pcNonRecDataTyCon integerTyConName
401 [] [] [smallIntegerDataCon, largeIntegerDataCon]
403 smallIntegerDataCon = pcDataCon smallIntegerDataConName
404 [] [] [intPrimTy] integerTyCon
405 largeIntegerDataCon = pcDataCon largeIntegerDataConName
406 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
410 %************************************************************************
412 \subsection[TysWiredIn-ext-type]{External types}
414 %************************************************************************
416 The compiler's foreign function interface supports the passing of a
417 restricted set of types as arguments and results (the restricting factor
421 isFFIArgumentTy :: DynFlags -> Safety -> Type -> Bool
422 -- Checks for valid argument type for a 'foreign import'
423 isFFIArgumentTy dflags safety ty
424 = checkRepTyCon (legalOutgoingTyCon dflags safety) ty
426 isFFIExternalTy :: Type -> Bool
427 -- Types that are allowed as arguments of a 'foreign export'
428 isFFIExternalTy ty = checkRepTyCon legalFEArgTyCon ty
430 isFFIImportResultTy :: DynFlags -> Type -> Bool
431 isFFIImportResultTy dflags ty
432 = checkRepTyCon (legalFIResultTyCon dflags) ty
434 isFFIExportResultTy :: Type -> Bool
435 isFFIExportResultTy ty = checkRepTyCon legalFEResultTyCon ty
437 isFFIDynArgumentTy :: Type -> Bool
438 -- The argument type of a foreign import dynamic must be Ptr, FunPtr, Addr,
439 -- or a newtype of either.
440 isFFIDynArgumentTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
442 isFFIDynResultTy :: Type -> Bool
443 -- The result type of a foreign export dynamic must be Ptr, FunPtr, Addr,
444 -- or a newtype of either.
445 isFFIDynResultTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
447 isFFILabelTy :: Type -> Bool
448 -- The type of a foreign label must be Ptr, FunPtr, Addr,
449 -- or a newtype of either.
450 isFFILabelTy = checkRepTyCon (\tc -> tc == ptrTyCon || tc == funPtrTyCon || tc == addrTyCon)
452 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
453 -- Look through newtypes
454 checkRepTyCon check_tc ty = case splitTyConApp_maybe ty of
455 Just (tycon, _) -> check_tc tycon
459 ----------------------------------------------
460 These chaps do the work; they are not exported
461 ----------------------------------------------
464 legalFEArgTyCon :: TyCon -> Bool
465 -- It's illegal to return foreign objects and (mutable)
466 -- bytearrays from a _ccall_ / foreign declaration
467 -- (or be passed them as arguments in foreign exported functions).
469 | getUnique tc `elem` [ foreignObjTyConKey, foreignPtrTyConKey,
470 byteArrayTyConKey, mutableByteArrayTyConKey ]
472 -- It's also illegal to make foreign exports that take unboxed
473 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
475 = boxedMarshalableTyCon tc
477 legalFIResultTyCon :: DynFlags -> TyCon -> Bool
478 legalFIResultTyCon dflags tc
479 | getUnique tc `elem`
480 [ foreignObjTyConKey, foreignPtrTyConKey,
481 byteArrayTyConKey, mutableByteArrayTyConKey ] = False
482 | tc == unitTyCon = True
483 | otherwise = marshalableTyCon dflags tc
485 legalFEResultTyCon :: TyCon -> Bool
486 legalFEResultTyCon tc
487 | getUnique tc `elem`
488 [ foreignObjTyConKey, foreignPtrTyConKey,
489 byteArrayTyConKey, mutableByteArrayTyConKey ] = False
490 | tc == unitTyCon = True
491 | otherwise = boxedMarshalableTyCon tc
493 legalOutgoingTyCon :: DynFlags -> Safety -> TyCon -> Bool
494 -- Checks validity of types going from Haskell -> external world
495 legalOutgoingTyCon dflags safety tc
496 | playSafe safety && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
499 = marshalableTyCon dflags tc
501 marshalableTyCon dflags tc
502 = (dopt Opt_GlasgowExts dflags && isUnLiftedTyCon tc)
503 || boxedMarshalableTyCon tc
505 boxedMarshalableTyCon tc
506 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey
507 , int32TyConKey, int64TyConKey
508 , wordTyConKey, word8TyConKey, word16TyConKey
509 , word32TyConKey, word64TyConKey
510 , floatTyConKey, doubleTyConKey
511 , addrTyConKey, ptrTyConKey, funPtrTyConKey
512 , charTyConKey, foreignObjTyConKey
515 , byteArrayTyConKey, mutableByteArrayTyConKey
521 %************************************************************************
523 \subsection[TysWiredIn-Bool]{The @Bool@ type}
525 %************************************************************************
527 An ordinary enumeration type, but deeply wired in. There are no
528 magical operations on @Bool@ (just the regular Prelude code).
530 {\em BEGIN IDLE SPECULATION BY SIMON}
532 This is not the only way to encode @Bool@. A more obvious coding makes
533 @Bool@ just a boxed up version of @Bool#@, like this:
536 data Bool = MkBool Bool#
539 Unfortunately, this doesn't correspond to what the Report says @Bool@
540 looks like! Furthermore, we get slightly less efficient code (I
541 think) with this coding. @gtInt@ would look like this:
544 gtInt :: Int -> Int -> Bool
545 gtInt x y = case x of I# x# ->
547 case (gtIntPrim x# y#) of
551 Notice that the result of the @gtIntPrim@ comparison has to be turned
552 into an integer (here called @b#@), and returned in a @MkBool@ box.
554 The @if@ expression would compile to this:
557 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
560 I think this code is a little less efficient than the previous code,
561 but I'm not certain. At all events, corresponding with the Report is
562 important. The interesting thing is that the language is expressive
563 enough to describe more than one alternative; and that a type doesn't
564 necessarily need to be a straightforwardly boxed version of its
565 primitive counterpart.
567 {\em END IDLE SPECULATION BY SIMON}
570 boolTy = mkTyConTy boolTyCon
572 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
573 [] [] [falseDataCon, trueDataCon]
575 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
576 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
578 falseDataConId = dataConId falseDataCon
579 trueDataConId = dataConId trueDataCon
582 %************************************************************************
584 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
586 %************************************************************************
588 Special syntax, deeply wired in, but otherwise an ordinary algebraic
591 data [] a = [] | a : (List a)
593 data (,) a b = (,,) a b
598 mkListTy :: Type -> Type
599 mkListTy ty = mkTyConApp listTyCon [ty]
601 listTyCon = pcRecDataTyCon listTyConName
602 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
604 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
605 consDataCon = pcDataCon consDataConName
606 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
607 -- Interesting: polymorphic recursion would help here.
608 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
609 -- gets the over-specific type (Type -> Type)
612 %************************************************************************
614 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
616 %************************************************************************
618 The tuple types are definitely magic, because they form an infinite
623 They have a special family of type constructors, of type @TyCon@
624 These contain the tycon arity, but don't require a Unique.
627 They have a special family of constructors, of type
628 @Id@. Again these contain their arity but don't need a Unique.
631 There should be a magic way of generating the info tables and
632 entry code for all tuples.
634 But at the moment we just compile a Haskell source
635 file\srcloc{lib/prelude/...} containing declarations like:
638 data Tuple2 a b = Tup2 a b
639 data Tuple3 a b c = Tup3 a b c
640 data Tuple4 a b c d = Tup4 a b c d
643 The print-names associated with the magic @Id@s for tuple constructors
644 ``just happen'' to be the same as those generated by these
648 The instance environment should have a magic way to know
649 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
650 so on. \ToDo{Not implemented yet.}
653 There should also be a way to generate the appropriate code for each
654 of these instances, but (like the info tables and entry code) it is
655 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
659 mkTupleTy :: Boxity -> Int -> [Type] -> Type
660 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
662 unitTy = mkTupleTy Boxed 0 []
665 %************************************************************************
667 \subsection{Wired In Type Constructors for Representation Types}
669 %************************************************************************
671 The following code defines the wired in datatypes cross, plus, unit
672 and c_of needed for the generic methods.
674 Ok, so the basic story is that for each type constructor I need to
675 create 2 things - a TyCon and a DataCon and then we are basically
676 ok. There are going to be no arguments passed to these functions
677 because -well- there is nothing to pass to these functions.
681 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
683 crossDataCon :: DataCon
684 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
687 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
689 inlDataCon, inrDataCon :: DataCon
690 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
691 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
693 genUnitTyCon :: TyCon -- The "1" type constructor for generics
694 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
696 genUnitDataCon :: DataCon
697 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon