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, mkAlgTyConRep
105 import BasicTypes ( Arity, RecFlag(..), EP(..), Boxity(..), isBoxed )
107 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
108 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
109 splitTyConApp_maybe, repType,
110 TauType, ClassContext )
111 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
113 import CmdLineOpts ( DynFlags, dopt_GlasgowExts )
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 = mkAlgTyConRep name kind
177 mod = nameModule name
178 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
179 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
181 pcDataCon :: Name -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
182 -- The unique is the first of two free uniques;
183 -- the first is used for the datacon itself and the worker;
184 -- the second is used for the wrapper.
186 pcDataCon name tyvars context arg_tys tycon
189 data_con = mkDataCon name
190 [ NotMarkedStrict | a <- arg_tys ]
191 [ {- no labelled fields -} ]
192 tyvars context [] [] arg_tys tycon work_id wrap_id
194 wrap_rdr = nameRdrName name
195 wrap_occ = rdrNameOcc wrap_rdr
196 mod = nameModule name
197 wrap_id = mkDataConWrapId data_con
199 work_occ = mkWorkerOcc wrap_occ
200 work_key = incrUnique (nameUnique name)
201 work_name = mkWiredInName mod work_occ work_key
202 work_id = mkDataConId work_name data_con
206 %************************************************************************
208 \subsection[TysWiredIn-tuples]{The tuple types}
210 %************************************************************************
213 tupleTyCon :: Boxity -> Arity -> TyCon
214 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
215 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
216 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
218 tupleCon :: Boxity -> Arity -> DataCon
219 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
220 tupleCon Boxed i = snd (boxedTupleArr ! i)
221 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
223 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
224 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
225 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
227 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
228 mk_tuple boxity arity = (tycon, tuple_con)
230 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
231 tc_name = mkWiredInName mod (mkOccFS tcName name_str) tc_uniq
232 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
233 res_kind | isBoxed boxity = boxedTypeKind
234 | otherwise = unboxedTypeKind
236 tyvars | isBoxed boxity = take arity alphaTyVars
237 | otherwise = take arity openAlphaTyVars
239 tuple_con = pcDataCon name tyvars [] tyvar_tys tycon
240 tyvar_tys = mkTyVarTys tyvars
241 (mod_name, name_str) = mkTupNameStr boxity arity
242 name = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
243 tc_uniq = mkTupleTyConUnique boxity arity
244 dc_uniq = mkTupleDataConUnique boxity arity
245 mod = mkPrelModule mod_name
246 gen_info = mk_tc_gen_info mod tc_uniq tc_name tycon
248 mk_tc_gen_info mod tc_uniq tc_name tycon
251 tc_occ_name = nameOccName tc_name
252 occ_name1 = mkGenOcc1 tc_occ_name
253 occ_name2 = mkGenOcc2 tc_occ_name
254 fn1_key = incrUnique tc_uniq
255 fn2_key = incrUnique fn1_key
256 name1 = mkWiredInName mod occ_name1 fn1_key
257 name2 = mkWiredInName mod occ_name2 fn2_key
258 gen_info = mkTyConGenInfo tycon name1 name2
259 Just (EP id1 id2) = gen_info
261 unitTyCon = tupleTyCon Boxed 0
262 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
264 pairTyCon = tupleTyCon Boxed 2
266 unboxedSingletonTyCon = tupleTyCon Unboxed 1
267 unboxedSingletonDataCon = tupleCon Unboxed 1
269 unboxedPairTyCon = tupleTyCon Unboxed 2
270 unboxedPairDataCon = tupleCon Unboxed 2
273 %************************************************************************
275 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
277 %************************************************************************
280 -- The Void type is represented as a data type with no constructors
281 -- It's a built in type (i.e. there's no way to define it in Haskell;
282 -- the nearest would be
284 -- data Void = -- No constructors!
286 -- ) It's boxed; there is only one value of this
287 -- type, namely "void", whose semantics is just bottom.
289 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
296 charTy = mkTyConTy charTyCon
298 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
299 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
301 stringTy = mkListTy charTy -- convenience only
305 intTy = mkTyConTy intTyCon
307 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
308 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
310 isIntTy :: Type -> Bool
311 isIntTy = isTyCon intTyConKey
316 wordTy = mkTyConTy wordTyCon
318 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
319 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
323 addrTy = mkTyConTy addrTyCon
325 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
326 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
328 isAddrTy :: Type -> Bool
329 isAddrTy = isTyCon addrTyConKey
333 floatTy = mkTyConTy floatTyCon
335 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
336 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
338 isFloatTy :: Type -> Bool
339 isFloatTy = isTyCon floatTyConKey
343 doubleTy = mkTyConTy doubleTyCon
345 isDoubleTy :: Type -> Bool
346 isDoubleTy = isTyCon doubleTyConKey
348 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
349 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
354 = pcNonRecDataTyCon stablePtrTyConName
355 alpha_tyvar [(True,False)] [stablePtrDataCon]
358 = pcDataCon stablePtrDataConName
359 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
364 = pcNonRecDataTyCon foreignObjTyConName
365 [] [] [foreignObjDataCon]
368 = pcDataCon foreignObjDataConName
369 [] [] [foreignObjPrimTy] foreignObjTyCon
371 isForeignObjTy :: Type -> Bool
372 isForeignObjTy = isTyCon foreignObjTyConKey
375 %************************************************************************
377 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
379 %************************************************************************
381 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
384 integerTy = mkTyConTy integerTyCon
386 integerTyCon = pcNonRecDataTyCon integerTyConName
387 [] [] [smallIntegerDataCon, largeIntegerDataCon]
389 smallIntegerDataCon = pcDataCon smallIntegerDataConName
390 [] [] [intPrimTy] integerTyCon
391 largeIntegerDataCon = pcDataCon largeIntegerDataConName
392 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
395 isIntegerTy :: Type -> Bool
396 isIntegerTy = isTyCon integerTyConKey
400 %************************************************************************
402 \subsection[TysWiredIn-ext-type]{External types}
404 %************************************************************************
406 The compiler's foreign function interface supports the passing of a
407 restricted set of types as arguments and results (the restricting factor
411 isFFIArgumentTy :: DynFlags -> Bool -> Type -> Bool
412 -- Checks for valid argument type for a 'foreign import'
413 isFFIArgumentTy dflags is_safe ty
414 = checkRepTyCon (legalOutgoingTyCon dflags is_safe) ty
416 isFFIExternalTy :: Type -> Bool
417 -- Types that are allowed as arguments of a 'foreign export'
418 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
420 isFFIResultTy :: Type -> Bool
421 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
422 -- Maybe we should distinguish between import and export, but
423 -- here we just choose the more restrictive 'incoming' predicate
424 -- But we allow () as well
425 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
427 isFFIDynArgumentTy :: Type -> Bool
428 -- The argument type of a foreign import dynamic must be either Addr, or
429 -- a newtype of Addr.
430 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
432 isFFIDynResultTy :: Type -> Bool
433 -- The result type of a foreign export dynamic must be either Addr, or
434 -- a newtype of Addr.
435 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
437 isFFILabelTy :: Type -> Bool
438 -- The type of a foreign label must be either Addr, or
439 -- a newtype of Addr.
440 isFFILabelTy = checkRepTyCon (== addrTyCon)
442 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
443 -- look through newtypes
444 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
446 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
447 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
448 Just (tycon, _) -> check_tc tycon
451 isTyCon :: Unique -> Type -> Bool
452 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
455 ----------------------------------------------
456 These chaps do the work; they are not exported
457 ----------------------------------------------
460 legalIncomingTyCon :: TyCon -> Bool
461 -- It's illegal to return foreign objects and (mutable)
462 -- bytearrays from a _ccall_ / foreign declaration
463 -- (or be passed them as arguments in foreign exported functions).
464 legalIncomingTyCon tc
465 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey,
466 mutableByteArrayTyConKey ]
468 -- It's also illegal to make foreign exports that take unboxed
469 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
471 = boxedMarshalableTyCon tc
473 legalOutgoingTyCon :: DynFlags -> Bool -> TyCon -> Bool
474 -- Checks validity of types going from Haskell -> external world
475 -- The boolean is true for a 'safe' call (when we don't want to
476 -- pass Haskell pointers to the world)
477 legalOutgoingTyCon dflags be_safe tc
478 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
481 = marshalableTyCon dflags tc
483 marshalableTyCon dflags tc
484 = (dopt_GlasgowExts dflags && isUnLiftedTyCon tc)
485 || boxedMarshalableTyCon tc
487 boxedMarshalableTyCon tc
488 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
489 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
490 , floatTyConKey, doubleTyConKey
491 , addrTyConKey, charTyConKey, foreignObjTyConKey
493 , byteArrayTyConKey, mutableByteArrayTyConKey
499 %************************************************************************
501 \subsection[TysWiredIn-Bool]{The @Bool@ type}
503 %************************************************************************
505 An ordinary enumeration type, but deeply wired in. There are no
506 magical operations on @Bool@ (just the regular Prelude code).
508 {\em BEGIN IDLE SPECULATION BY SIMON}
510 This is not the only way to encode @Bool@. A more obvious coding makes
511 @Bool@ just a boxed up version of @Bool#@, like this:
514 data Bool = MkBool Bool#
517 Unfortunately, this doesn't correspond to what the Report says @Bool@
518 looks like! Furthermore, we get slightly less efficient code (I
519 think) with this coding. @gtInt@ would look like this:
522 gtInt :: Int -> Int -> Bool
523 gtInt x y = case x of I# x# ->
525 case (gtIntPrim x# y#) of
529 Notice that the result of the @gtIntPrim@ comparison has to be turned
530 into an integer (here called @b#@), and returned in a @MkBool@ box.
532 The @if@ expression would compile to this:
535 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
538 I think this code is a little less efficient than the previous code,
539 but I'm not certain. At all events, corresponding with the Report is
540 important. The interesting thing is that the language is expressive
541 enough to describe more than one alternative; and that a type doesn't
542 necessarily need to be a straightforwardly boxed version of its
543 primitive counterpart.
545 {\em END IDLE SPECULATION BY SIMON}
548 boolTy = mkTyConTy boolTyCon
550 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
551 [] [] [falseDataCon, trueDataCon]
553 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
554 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
556 falseDataConId = dataConId falseDataCon
557 trueDataConId = dataConId trueDataCon
560 %************************************************************************
562 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
564 %************************************************************************
566 Special syntax, deeply wired in, but otherwise an ordinary algebraic
569 data [] a = [] | a : (List a)
571 data (,) a b = (,,) a b
576 mkListTy :: Type -> Type
577 mkListTy ty = mkTyConApp listTyCon [ty]
579 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_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