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(..), 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 = mkAlgTyConRep name kind
176 mod = nameModule name
177 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
178 gen_info = mk_tc_gen_info mod (nameUnique name) name tycon
180 pcDataCon :: Name -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
181 -- The unique is the first of two free uniques;
182 -- the first is used for the datacon itself and the worker;
183 -- the second is used for the wrapper.
185 pcDataCon name tyvars context arg_tys tycon
188 data_con = mkDataCon name
189 [ NotMarkedStrict | a <- arg_tys ]
190 [ {- no labelled fields -} ]
191 tyvars context [] [] arg_tys tycon work_id wrap_id
193 wrap_rdr = nameRdrName name
194 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
260 unitTyCon = tupleTyCon Boxed 0
261 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
263 pairTyCon = tupleTyCon Boxed 2
265 unboxedSingletonTyCon = tupleTyCon Unboxed 1
266 unboxedSingletonDataCon = tupleCon Unboxed 1
268 unboxedPairTyCon = tupleTyCon Unboxed 2
269 unboxedPairDataCon = tupleCon Unboxed 2
272 %************************************************************************
274 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
276 %************************************************************************
279 -- The Void type is represented as a data type with no constructors
280 -- It's a built in type (i.e. there's no way to define it in Haskell;
281 -- the nearest would be
283 -- data Void = -- No constructors!
285 -- ) It's boxed; there is only one value of this
286 -- type, namely "void", whose semantics is just bottom.
288 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
295 charTy = mkTyConTy charTyCon
297 charTyCon = pcNonRecDataTyCon charTyConName [] [] [charDataCon]
298 charDataCon = pcDataCon charDataConName [] [] [charPrimTy] charTyCon
300 stringTy = mkListTy charTy -- convenience only
304 intTy = mkTyConTy intTyCon
306 intTyCon = pcNonRecDataTyCon intTyConName [] [] [intDataCon]
307 intDataCon = pcDataCon intDataConName [] [] [intPrimTy] intTyCon
309 isIntTy :: Type -> Bool
310 isIntTy = isTyCon intTyConKey
315 wordTy = mkTyConTy wordTyCon
317 wordTyCon = pcNonRecDataTyCon wordTyConName [] [] [wordDataCon]
318 wordDataCon = pcDataCon wordDataConName [] [] [wordPrimTy] wordTyCon
322 addrTy = mkTyConTy addrTyCon
324 addrTyCon = pcNonRecDataTyCon addrTyConName [] [] [addrDataCon]
325 addrDataCon = pcDataCon addrDataConName [] [] [addrPrimTy] addrTyCon
327 isAddrTy :: Type -> Bool
328 isAddrTy = isTyCon addrTyConKey
332 floatTy = mkTyConTy floatTyCon
334 floatTyCon = pcNonRecDataTyCon floatTyConName [] [] [floatDataCon]
335 floatDataCon = pcDataCon floatDataConName [] [] [floatPrimTy] floatTyCon
337 isFloatTy :: Type -> Bool
338 isFloatTy = isTyCon floatTyConKey
342 doubleTy = mkTyConTy doubleTyCon
344 isDoubleTy :: Type -> Bool
345 isDoubleTy = isTyCon doubleTyConKey
347 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [] [doubleDataCon]
348 doubleDataCon = pcDataCon doubleDataConName [] [] [doublePrimTy] doubleTyCon
353 = pcNonRecDataTyCon stablePtrTyConName
354 alpha_tyvar [(True,False)] [stablePtrDataCon]
357 = pcDataCon stablePtrDataConName
358 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
363 = pcNonRecDataTyCon foreignObjTyConName
364 [] [] [foreignObjDataCon]
367 = pcDataCon foreignObjDataConName
368 [] [] [foreignObjPrimTy] foreignObjTyCon
370 isForeignObjTy :: Type -> Bool
371 isForeignObjTy = isTyCon foreignObjTyConKey
374 %************************************************************************
376 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
378 %************************************************************************
380 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
383 integerTy = mkTyConTy integerTyCon
385 integerTyCon = pcNonRecDataTyCon integerTyConName
386 [] [] [smallIntegerDataCon, largeIntegerDataCon]
388 smallIntegerDataCon = pcDataCon smallIntegerDataConName
389 [] [] [intPrimTy] integerTyCon
390 largeIntegerDataCon = pcDataCon largeIntegerDataConName
391 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
394 isIntegerTy :: Type -> Bool
395 isIntegerTy = isTyCon integerTyConKey
399 %************************************************************************
401 \subsection[TysWiredIn-ext-type]{External types}
403 %************************************************************************
405 The compiler's foreign function interface supports the passing of a
406 restricted set of types as arguments and results (the restricting factor
410 isFFIArgumentTy :: DynFlags -> Bool -> Type -> Bool
411 -- Checks for valid argument type for a 'foreign import'
412 isFFIArgumentTy dflags is_safe ty
413 = checkRepTyCon (legalOutgoingTyCon dflags is_safe) ty
415 isFFIExternalTy :: Type -> Bool
416 -- Types that are allowed as arguments of a 'foreign export'
417 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
419 isFFIResultTy :: Type -> Bool
420 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
421 -- Maybe we should distinguish between import and export, but
422 -- here we just choose the more restrictive 'incoming' predicate
423 -- But we allow () as well
424 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
426 isFFIDynArgumentTy :: Type -> Bool
427 -- The argument type of a foreign import dynamic must be either Addr, or
428 -- a newtype of Addr.
429 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
431 isFFIDynResultTy :: Type -> Bool
432 -- The result type of a foreign export dynamic must be either Addr, or
433 -- a newtype of Addr.
434 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
436 isFFILabelTy :: Type -> Bool
437 -- The type of a foreign label must be either Addr, or
438 -- a newtype of Addr.
439 isFFILabelTy = checkRepTyCon (== addrTyCon)
441 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
442 -- look through newtypes
443 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
445 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
446 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
447 Just (tycon, _) -> check_tc tycon
450 isTyCon :: Unique -> Type -> Bool
451 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
454 ----------------------------------------------
455 These chaps do the work; they are not exported
456 ----------------------------------------------
459 legalIncomingTyCon :: TyCon -> Bool
460 -- It's illegal to return foreign objects and (mutable)
461 -- bytearrays from a _ccall_ / foreign declaration
462 -- (or be passed them as arguments in foreign exported functions).
463 legalIncomingTyCon tc
464 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey,
465 mutableByteArrayTyConKey ]
467 -- It's also illegal to make foreign exports that take unboxed
468 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
470 = boxedMarshalableTyCon tc
472 legalOutgoingTyCon :: DynFlags -> Bool -> TyCon -> Bool
473 -- Checks validity of types going from Haskell -> external world
474 -- The boolean is true for a 'safe' call (when we don't want to
475 -- pass Haskell pointers to the world)
476 legalOutgoingTyCon dflags be_safe tc
477 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
480 = marshalableTyCon dflags tc
482 marshalableTyCon dflags tc
483 = (dopt Opt_GlasgowExts dflags && isUnLiftedTyCon tc)
484 || boxedMarshalableTyCon tc
486 boxedMarshalableTyCon tc
487 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
488 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
489 , floatTyConKey, doubleTyConKey
490 , addrTyConKey, charTyConKey, foreignObjTyConKey
492 , byteArrayTyConKey, mutableByteArrayTyConKey
498 %************************************************************************
500 \subsection[TysWiredIn-Bool]{The @Bool@ type}
502 %************************************************************************
504 An ordinary enumeration type, but deeply wired in. There are no
505 magical operations on @Bool@ (just the regular Prelude code).
507 {\em BEGIN IDLE SPECULATION BY SIMON}
509 This is not the only way to encode @Bool@. A more obvious coding makes
510 @Bool@ just a boxed up version of @Bool#@, like this:
513 data Bool = MkBool Bool#
516 Unfortunately, this doesn't correspond to what the Report says @Bool@
517 looks like! Furthermore, we get slightly less efficient code (I
518 think) with this coding. @gtInt@ would look like this:
521 gtInt :: Int -> Int -> Bool
522 gtInt x y = case x of I# x# ->
524 case (gtIntPrim x# y#) of
528 Notice that the result of the @gtIntPrim@ comparison has to be turned
529 into an integer (here called @b#@), and returned in a @MkBool@ box.
531 The @if@ expression would compile to this:
534 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
537 I think this code is a little less efficient than the previous code,
538 but I'm not certain. At all events, corresponding with the Report is
539 important. The interesting thing is that the language is expressive
540 enough to describe more than one alternative; and that a type doesn't
541 necessarily need to be a straightforwardly boxed version of its
542 primitive counterpart.
544 {\em END IDLE SPECULATION BY SIMON}
547 boolTy = mkTyConTy boolTyCon
549 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConName
550 [] [] [falseDataCon, trueDataCon]
552 falseDataCon = pcDataCon falseDataConName [] [] [] boolTyCon
553 trueDataCon = pcDataCon trueDataConName [] [] [] boolTyCon
555 falseDataConId = dataConId falseDataCon
556 trueDataConId = dataConId trueDataCon
559 %************************************************************************
561 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
563 %************************************************************************
565 Special syntax, deeply wired in, but otherwise an ordinary algebraic
568 data [] a = [] | a : (List a)
570 data (,) a b = (,,) a b
575 mkListTy :: Type -> Type
576 mkListTy ty = mkTyConApp listTyCon [ty]
578 listTyCon = pcRecDataTyCon listTyConName
579 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
581 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] [] listTyCon
582 consDataCon = pcDataCon consDataConName
583 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
584 -- Interesting: polymorphic recursion would help here.
585 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
586 -- gets the over-specific type (Type -> Type)
589 %************************************************************************
591 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
593 %************************************************************************
595 The tuple types are definitely magic, because they form an infinite
600 They have a special family of type constructors, of type @TyCon@
601 These contain the tycon arity, but don't require a Unique.
604 They have a special family of constructors, of type
605 @Id@. Again these contain their arity but don't need a Unique.
608 There should be a magic way of generating the info tables and
609 entry code for all tuples.
611 But at the moment we just compile a Haskell source
612 file\srcloc{lib/prelude/...} containing declarations like:
615 data Tuple2 a b = Tup2 a b
616 data Tuple3 a b c = Tup3 a b c
617 data Tuple4 a b c d = Tup4 a b c d
620 The print-names associated with the magic @Id@s for tuple constructors
621 ``just happen'' to be the same as those generated by these
625 The instance environment should have a magic way to know
626 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
627 so on. \ToDo{Not implemented yet.}
630 There should also be a way to generate the appropriate code for each
631 of these instances, but (like the info tables and entry code) it is
632 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
636 mkTupleTy :: Boxity -> Int -> [Type] -> Type
637 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
639 unitTy = mkTupleTy Boxed 0 []
642 %************************************************************************
644 \subsection{Wired In Type Constructors for Representation Types}
646 %************************************************************************
648 The following code defines the wired in datatypes cross, plus, unit
649 and c_of needed for the generic methods.
651 Ok, so the basic story is that for each type constructor I need to
652 create 2 things - a TyCon and a DataCon and then we are basically
653 ok. There are going to be no arguments passed to these functions
654 because -well- there is nothing to pass to these functions.
658 crossTyCon = pcNonRecDataTyCon crossTyConName alpha_beta_tyvars [] [crossDataCon]
660 crossDataCon :: DataCon
661 crossDataCon = pcDataCon crossDataConName alpha_beta_tyvars [] [alphaTy, betaTy] crossTyCon
664 plusTyCon = pcNonRecDataTyCon plusTyConName alpha_beta_tyvars [] [inlDataCon, inrDataCon]
666 inlDataCon, inrDataCon :: DataCon
667 inlDataCon = pcDataCon inlDataConName alpha_beta_tyvars [] [alphaTy] plusTyCon
668 inrDataCon = pcDataCon inrDataConName alpha_beta_tyvars [] [betaTy] plusTyCon
670 genUnitTyCon :: TyCon -- The "1" type constructor for generics
671 genUnitTyCon = pcNonRecDataTyCon genUnitTyConName [] [] [genUnitDataCon]
673 genUnitDataCon :: DataCon
674 genUnitDataCon = pcDataCon genUnitDataConName [] [] [] genUnitTyCon