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.''
27 falseDataCon, falseDataConId,
52 unitTyCon, unitDataConId, pairTyCon,
53 unboxedSingletonTyCon, unboxedSingletonDataCon,
54 unboxedPairTyCon, unboxedPairDataCon,
58 trueDataCon, trueDataConId,
65 isFFIArgumentTy, -- :: Bool -> Type -> Bool
66 isFFIResultTy, -- :: Type -> Bool
67 isFFIExternalTy, -- :: Type -> Bool
68 isFFIDynArgumentTy, -- :: Type -> Bool
69 isFFIDynResultTy, -- :: Type -> Bool
70 isFFILabelTy, -- :: Type -> Bool
71 isAddrTy, -- :: Type -> Bool
72 isForeignObjTy -- :: Type -> Bool
76 #include "HsVersions.h"
78 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
85 import Constants ( mAX_TUPLE_SIZE )
86 import Module ( Module, mkPrelModule )
87 import Name ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, mkWorkerOcc, dataName )
88 import DataCon ( DataCon, StrictnessMark(..), mkDataCon, dataConId )
89 import Var ( TyVar, tyVarKind )
90 import TyCon ( TyCon, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
91 mkAlgTyCon, mkSynTyCon, mkTupleTyCon, isUnLiftedTyCon
93 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
94 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
95 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
97 splitTyConApp_maybe, repType,
98 TauType, ClassContext )
99 import Unique ( incrUnique, mkTupleTyConUnique, mkTupleDataConUnique )
101 import CmdLineOpts ( opt_GlasgowExts )
104 alpha_tyvar = [alphaTyVar]
106 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
108 pcRecDataTyCon, pcNonRecDataTyCon
109 :: Unique{-TyConKey-} -> Module -> FAST_STRING
110 -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
112 pcRecDataTyCon = pcTyCon DataTyCon Recursive
113 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
115 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
118 tycon = mkAlgTyCon name kind
128 name = mkWiredInTyConName key mod str tycon
129 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
131 pcSynTyCon key mod str kind arity tyvars expansion argvrcs -- this fun never used!
134 tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
135 name = mkWiredInTyConName key mod str tycon
137 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
138 -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
139 -- The unique is the first of two free uniques;
140 -- the first is used for the datacon itself and the worker;
141 -- the second is used for the wrapper.
142 pcDataCon wrap_key mod str tyvars context arg_tys tycon
145 data_con = mkDataCon wrap_name
146 [ NotMarkedStrict | a <- arg_tys ]
147 [ {- no labelled fields -} ]
148 tyvars context [] [] arg_tys tycon work_id wrap_id
150 work_occ = mkWorkerOcc wrap_occ
151 work_key = incrUnique wrap_key
152 work_name = mkWiredInIdName work_key mod work_occ work_id
153 work_id = mkDataConId work_name data_con
155 wrap_occ = mkSrcOccFS dataName str
156 wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
157 wrap_id = mkDataConWrapId data_con
161 %************************************************************************
163 \subsection[TysWiredIn-tuples]{The tuple types}
165 %************************************************************************
168 tupleTyCon :: Boxity -> Arity -> TyCon
169 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
170 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
171 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
173 tupleCon :: Boxity -> Arity -> DataCon
174 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
175 tupleCon Boxed i = snd (boxedTupleArr ! i)
176 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
178 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
179 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
180 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
182 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
183 mk_tuple boxity arity = (tycon, tuple_con)
185 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity
186 tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
187 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
188 res_kind | isBoxed boxity = boxedTypeKind
189 | otherwise = unboxedTypeKind
191 tyvars | isBoxed boxity = take arity alphaTyVars
192 | otherwise = take arity openAlphaTyVars
194 tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
195 tyvar_tys = mkTyVarTys tyvars
196 (mod_name, name_str) = mkTupNameStr boxity arity
197 tc_uniq = mkTupleTyConUnique boxity arity
198 dc_uniq = mkTupleDataConUnique boxity arity
199 mod = mkPrelModule mod_name
201 unitTyCon = tupleTyCon Boxed 0
202 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
204 pairTyCon = tupleTyCon Boxed 2
206 unboxedSingletonTyCon = tupleTyCon Unboxed 1
207 unboxedSingletonDataCon = tupleCon Unboxed 1
209 unboxedPairTyCon = tupleTyCon Unboxed 2
210 unboxedPairDataCon = tupleCon Unboxed 2
213 %************************************************************************
215 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
217 %************************************************************************
220 -- The Void type is represented as a data type with no constructors
221 -- It's a built in type (i.e. there's no way to define it in Haskell;
222 -- the nearest would be
224 -- data Void = -- No constructors!
226 -- ) It's boxed; there is only one value of this
227 -- type, namely "void", whose semantics is just bottom.
229 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
236 charTy = mkTyConTy charTyCon
238 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [] [charDataCon]
239 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
241 stringTy = mkListTy charTy -- convenience only
245 intTy = mkTyConTy intTyCon
247 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
248 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
250 isIntTy :: Type -> Bool
251 isIntTy = isTyCon intTyConKey
256 wordTy = mkTyConTy wordTyCon
258 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [] [wordDataCon]
259 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
263 addrTy = mkTyConTy addrTyCon
265 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
266 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
268 isAddrTy :: Type -> Bool
269 isAddrTy = isTyCon addrTyConKey
273 floatTy = mkTyConTy floatTyCon
275 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
276 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
278 isFloatTy :: Type -> Bool
279 isFloatTy = isTyCon floatTyConKey
283 doubleTy = mkTyConTy doubleTyCon
285 isDoubleTy :: Type -> Bool
286 isDoubleTy = isTyCon doubleTyConKey
288 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
289 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
294 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
295 alpha_tyvar [(True,False)] [stablePtrDataCon]
298 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
299 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
304 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
305 [] [] [foreignObjDataCon]
308 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
309 [] [] [foreignObjPrimTy] foreignObjTyCon
311 isForeignObjTy :: Type -> Bool
312 isForeignObjTy = isTyCon foreignObjTyConKey
315 %************************************************************************
317 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
319 %************************************************************************
321 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
324 integerTy = mkTyConTy integerTyCon
326 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
327 [] [] [smallIntegerDataCon, largeIntegerDataCon]
329 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
330 [] [] [intPrimTy] integerTyCon
331 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
332 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
335 isIntegerTy :: Type -> Bool
336 isIntegerTy = isTyCon integerTyConKey
340 %************************************************************************
342 \subsection[TysWiredIn-ext-type]{External types}
344 %************************************************************************
346 The compiler's foreign function interface supports the passing of a
347 restricted set of types as arguments and results (the restricting factor
351 isFFIArgumentTy :: Bool -> Type -> Bool
352 -- Checks for valid argument type for a 'foreign import'
353 isFFIArgumentTy is_safe ty = checkRepTyCon (legalOutgoingTyCon is_safe) ty
355 isFFIExternalTy :: Type -> Bool
356 -- Types that are allowed as arguments of a 'foreign export'
357 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
359 isFFIResultTy :: Type -> Bool
360 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
361 -- Maybe we should distinguish between import and export, but
362 -- here we just choose the more restrictive 'incoming' predicate
363 -- But we allow () as well
364 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
366 isFFIDynArgumentTy :: Type -> Bool
367 -- The argument type of a foreign import dynamic must be either Addr, or
368 -- a newtype of Addr.
369 isFFIDynArgumentTy = checkRepTyCon (== addrTyCon)
371 isFFIDynResultTy :: Type -> Bool
372 -- The result type of a foreign export dynamic must be either Addr, or
373 -- a newtype of Addr.
374 isFFIDynResultTy = checkRepTyCon (== addrTyCon)
376 isFFILabelTy :: Type -> Bool
377 -- The type of a foreign label must be either Addr, or
378 -- a newtype of Addr.
379 isFFILabelTy = checkRepTyCon (== addrTyCon)
381 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
382 -- look through newtypes
383 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
385 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
386 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
387 Just (tycon, _) -> check_tc tycon
390 isTyCon :: Unique -> Type -> Bool
391 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
394 ----------------------------------------------
395 These chaps do the work; they are not exported
396 ----------------------------------------------
399 legalIncomingTyCon :: TyCon -> Bool
400 -- It's illegal to return foreign objects and (mutable)
401 -- bytearrays from a _ccall_ / foreign declaration
402 -- (or be passed them as arguments in foreign exported functions).
403 legalIncomingTyCon tc
404 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
406 -- It's also illegal to make foreign exports that take unboxed
407 -- arguments. The RTS API currently can't invoke such things. --SDM 7/2000
409 = boxedMarshalableTyCon tc
411 legalOutgoingTyCon :: Bool -> TyCon -> Bool
412 -- Checks validity of types going from Haskell -> external world
413 -- The boolean is true for a 'safe' call (when we don't want to
414 -- pass Haskell pointers to the world)
415 legalOutgoingTyCon be_safe tc
416 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
419 = marshalableTyCon tc
422 = (opt_GlasgowExts && isUnLiftedTyCon tc)
423 || boxedMarshalableTyCon tc
425 boxedMarshalableTyCon tc
426 = getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
427 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
428 , floatTyConKey, doubleTyConKey
429 , addrTyConKey, charTyConKey, foreignObjTyConKey
431 , byteArrayTyConKey, mutableByteArrayTyConKey
437 %************************************************************************
439 \subsection[TysWiredIn-Bool]{The @Bool@ type}
441 %************************************************************************
443 An ordinary enumeration type, but deeply wired in. There are no
444 magical operations on @Bool@ (just the regular Prelude code).
446 {\em BEGIN IDLE SPECULATION BY SIMON}
448 This is not the only way to encode @Bool@. A more obvious coding makes
449 @Bool@ just a boxed up version of @Bool#@, like this:
452 data Bool = MkBool Bool#
455 Unfortunately, this doesn't correspond to what the Report says @Bool@
456 looks like! Furthermore, we get slightly less efficient code (I
457 think) with this coding. @gtInt@ would look like this:
460 gtInt :: Int -> Int -> Bool
461 gtInt x y = case x of I# x# ->
463 case (gtIntPrim x# y#) of
467 Notice that the result of the @gtIntPrim@ comparison has to be turned
468 into an integer (here called @b#@), and returned in a @MkBool@ box.
470 The @if@ expression would compile to this:
473 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
476 I think this code is a little less efficient than the previous code,
477 but I'm not certain. At all events, corresponding with the Report is
478 important. The interesting thing is that the language is expressive
479 enough to describe more than one alternative; and that a type doesn't
480 necessarily need to be a straightforwardly boxed version of its
481 primitive counterpart.
483 {\em END IDLE SPECULATION BY SIMON}
486 boolTy = mkTyConTy boolTyCon
488 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey
489 pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
491 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
492 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
494 falseDataConId = dataConId falseDataCon
495 trueDataConId = dataConId trueDataCon
498 %************************************************************************
500 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
502 %************************************************************************
504 Special syntax, deeply wired in, but otherwise an ordinary algebraic
507 data [] a = [] | a : (List a)
509 data (,) a b = (,,) a b
514 mkListTy :: Type -> Type
515 mkListTy ty = mkTyConApp listTyCon [ty]
517 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
519 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
520 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
522 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
523 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
524 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
525 -- Interesting: polymorphic recursion would help here.
526 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
527 -- gets the over-specific type (Type -> Type)
530 %************************************************************************
532 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
534 %************************************************************************
536 The tuple types are definitely magic, because they form an infinite
541 They have a special family of type constructors, of type @TyCon@
542 These contain the tycon arity, but don't require a Unique.
545 They have a special family of constructors, of type
546 @Id@. Again these contain their arity but don't need a Unique.
549 There should be a magic way of generating the info tables and
550 entry code for all tuples.
552 But at the moment we just compile a Haskell source
553 file\srcloc{lib/prelude/...} containing declarations like:
556 data Tuple2 a b = Tup2 a b
557 data Tuple3 a b c = Tup3 a b c
558 data Tuple4 a b c d = Tup4 a b c d
561 The print-names associated with the magic @Id@s for tuple constructors
562 ``just happen'' to be the same as those generated by these
566 The instance environment should have a magic way to know
567 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
568 so on. \ToDo{Not implemented yet.}
571 There should also be a way to generate the appropriate code for each
572 of these instances, but (like the info tables and entry code) it is
573 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
577 mkTupleTy :: Boxity -> Int -> [Type] -> Type
578 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
580 unitTy = mkTupleTy Boxed 0 []