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 isAddrTy, -- :: Type -> Bool
69 isForeignObjTy -- :: Type -> Bool
73 #include "HsVersions.h"
75 import {-# SOURCE #-} MkId( mkDataConId, mkDataConWrapId )
82 import Constants ( mAX_TUPLE_SIZE )
83 import Module ( Module, mkPrelModule )
84 import Name ( mkWiredInTyConName, mkWiredInIdName, mkSrcOccFS, mkWorkerOcc, dataName )
85 import DataCon ( DataCon, StrictnessMark(..), mkDataCon, dataConId )
86 import Var ( TyVar, tyVarKind )
87 import TyCon ( TyCon, AlgTyConFlavour(..), ArgVrcs, tyConDataCons,
88 mkAlgTyCon, mkSynTyCon, mkTupleTyCon, isUnLiftedTyCon
90 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
91 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
92 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
94 splitTyConApp_maybe, repType,
95 TauType, ClassContext )
97 import CmdLineOpts ( opt_GlasgowExts )
100 alpha_tyvar = [alphaTyVar]
102 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
104 pcRecDataTyCon, pcNonRecDataTyCon
105 :: Unique{-TyConKey-} -> Module -> FAST_STRING
106 -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
108 pcRecDataTyCon = pcTyCon DataTyCon Recursive
109 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
111 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
114 tycon = mkAlgTyCon name kind
124 name = mkWiredInTyConName key mod str tycon
125 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
127 pcSynTyCon key mod str kind arity tyvars expansion argvrcs -- this fun never used!
130 tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
131 name = mkWiredInTyConName key mod str tycon
133 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
134 -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
135 -- The unique is the first of two free uniques;
136 -- the first is used for the datacon itself and the worker;
137 -- the second is used for the wrapper.
138 pcDataCon wrap_key mod str tyvars context arg_tys tycon
141 data_con = mkDataCon wrap_name
142 [ NotMarkedStrict | a <- arg_tys ]
143 [ {- no labelled fields -} ]
144 tyvars context [] [] arg_tys tycon work_id wrap_id
146 work_occ = mkWorkerOcc wrap_occ
147 work_key = incrUnique wrap_key
148 work_name = mkWiredInIdName work_key mod work_occ work_id
149 work_id = mkDataConId work_name data_con
151 wrap_occ = mkSrcOccFS dataName str
152 wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
153 wrap_id = mkDataConWrapId data_con
157 %************************************************************************
159 \subsection[TysWiredIn-tuples]{The tuple types}
161 %************************************************************************
164 tupleTyCon :: Boxity -> Arity -> TyCon
165 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
166 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
167 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
169 tupleCon :: Boxity -> Arity -> DataCon
170 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
171 tupleCon Boxed i = snd (boxedTupleArr ! i)
172 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
174 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
175 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
176 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
178 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
179 mk_tuple boxity arity = (tycon, tuple_con)
181 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity
182 tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
183 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
184 res_kind | isBoxed boxity = boxedTypeKind
185 | otherwise = unboxedTypeKind
187 tyvars | isBoxed boxity = take arity alphaTyVars
188 | otherwise = take arity openAlphaTyVars
190 tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
191 tyvar_tys = mkTyVarTys tyvars
192 (mod_name, name_str) = mkTupNameStr boxity arity
193 tc_uniq = mkTupleTyConUnique boxity arity
194 dc_uniq = mkTupleDataConUnique boxity arity
195 mod = mkPrelModule mod_name
197 unitTyCon = tupleTyCon Boxed 0
198 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
200 pairTyCon = tupleTyCon Boxed 2
202 unboxedSingletonTyCon = tupleTyCon Unboxed 1
203 unboxedSingletonDataCon = tupleCon Unboxed 1
205 unboxedPairTyCon = tupleTyCon Unboxed 2
206 unboxedPairDataCon = tupleCon Unboxed 2
209 %************************************************************************
211 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
213 %************************************************************************
216 -- The Void type is represented as a data type with no constructors
217 -- It's a built in type (i.e. there's no way to define it in Haskell;
218 -- the nearest would be
220 -- data Void = -- No constructors!
222 -- ) It's boxed; there is only one value of this
223 -- type, namely "void", whose semantics is just bottom.
225 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
232 charTy = mkTyConTy charTyCon
234 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [] [charDataCon]
235 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
237 stringTy = mkListTy charTy -- convenience only
241 intTy = mkTyConTy intTyCon
243 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
244 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
246 isIntTy :: Type -> Bool
247 isIntTy = isTyCon intTyConKey
252 wordTy = mkTyConTy wordTyCon
254 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [] [wordDataCon]
255 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
259 addrTy = mkTyConTy addrTyCon
261 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
262 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
264 isAddrTy :: Type -> Bool
265 isAddrTy = isTyCon addrTyConKey
269 floatTy = mkTyConTy floatTyCon
271 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
272 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
274 isFloatTy :: Type -> Bool
275 isFloatTy = isTyCon floatTyConKey
279 doubleTy = mkTyConTy doubleTyCon
281 isDoubleTy :: Type -> Bool
282 isDoubleTy = isTyCon doubleTyConKey
284 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
285 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
290 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
291 alpha_tyvar [(True,False)] [stablePtrDataCon]
294 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
295 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
300 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
301 [] [] [foreignObjDataCon]
304 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
305 [] [] [foreignObjPrimTy] foreignObjTyCon
307 isForeignObjTy :: Type -> Bool
308 isForeignObjTy = isTyCon foreignObjTyConKey
311 %************************************************************************
313 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
315 %************************************************************************
317 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
320 integerTy = mkTyConTy integerTyCon
322 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
323 [] [] [smallIntegerDataCon, largeIntegerDataCon]
325 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
326 [] [] [intPrimTy] integerTyCon
327 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
328 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
331 isIntegerTy :: Type -> Bool
332 isIntegerTy = isTyCon integerTyConKey
336 %************************************************************************
338 \subsection[TysWiredIn-ext-type]{External types}
340 %************************************************************************
342 The compiler's foreign function interface supports the passing of a
343 restricted set of types as arguments and results (the restricting factor
347 isFFIArgumentTy :: Bool -> Type -> Bool
348 -- Checks for valid argument type for a 'foreign import'
349 isFFIArgumentTy is_safe ty = checkRepTyCon (legalOutgoingTyCon is_safe) ty
351 isFFIExternalTy :: Type -> Bool
352 -- Types that are allowed as arguments of a 'foreign export'
353 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
355 isFFIResultTy :: Type -> Bool
356 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
357 -- Maybe we should distinguish between import and export, but
358 -- here we just choose the more restrictive 'incoming' predicate
359 -- But we allow () as well
360 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
362 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
363 -- look through newtypes
364 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
366 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
367 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
368 Just (tycon, _) -> check_tc tycon
371 isTyCon :: Unique -> Type -> Bool
372 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
375 ----------------------------------------------
376 These chaps do the work; they are not exported
377 ----------------------------------------------
380 legalIncomingTyCon :: TyCon -> Bool
381 -- It's illegal to return foreign objects and (mutable)
382 -- bytearrays from a _ccall_ / foreign declaration
383 -- (or be passed them as arguments in foreign exported functions).
384 legalIncomingTyCon tc
385 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
388 = marshalableTyCon tc
390 legalOutgoingTyCon :: Bool -> TyCon -> Bool
391 -- Checks validity of types going from Haskell -> external world
392 -- The boolean is true for a 'safe' call (when we don't want to
393 -- pass Haskell pointers to the world)
394 legalOutgoingTyCon be_safe tc
395 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
398 = marshalableTyCon tc
401 = (opt_GlasgowExts && isUnLiftedTyCon tc)
402 || getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
403 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
404 , floatTyConKey, doubleTyConKey
405 , addrTyConKey, charTyConKey, foreignObjTyConKey
407 , byteArrayTyConKey, mutableByteArrayTyConKey
413 %************************************************************************
415 \subsection[TysWiredIn-Bool]{The @Bool@ type}
417 %************************************************************************
419 An ordinary enumeration type, but deeply wired in. There are no
420 magical operations on @Bool@ (just the regular Prelude code).
422 {\em BEGIN IDLE SPECULATION BY SIMON}
424 This is not the only way to encode @Bool@. A more obvious coding makes
425 @Bool@ just a boxed up version of @Bool#@, like this:
428 data Bool = MkBool Bool#
431 Unfortunately, this doesn't correspond to what the Report says @Bool@
432 looks like! Furthermore, we get slightly less efficient code (I
433 think) with this coding. @gtInt@ would look like this:
436 gtInt :: Int -> Int -> Bool
437 gtInt x y = case x of I# x# ->
439 case (gtIntPrim x# y#) of
443 Notice that the result of the @gtIntPrim@ comparison has to be turned
444 into an integer (here called @b#@), and returned in a @MkBool@ box.
446 The @if@ expression would compile to this:
449 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
452 I think this code is a little less efficient than the previous code,
453 but I'm not certain. At all events, corresponding with the Report is
454 important. The interesting thing is that the language is expressive
455 enough to describe more than one alternative; and that a type doesn't
456 necessarily need to be a straightforwardly boxed version of its
457 primitive counterpart.
459 {\em END IDLE SPECULATION BY SIMON}
462 boolTy = mkTyConTy boolTyCon
464 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey
465 pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
467 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
468 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
470 falseDataConId = dataConId falseDataCon
471 trueDataConId = dataConId trueDataCon
474 %************************************************************************
476 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
478 %************************************************************************
480 Special syntax, deeply wired in, but otherwise an ordinary algebraic
483 data [] a = [] | a : (List a)
485 data (,) a b = (,,) a b
490 mkListTy :: Type -> Type
491 mkListTy ty = mkTyConApp listTyCon [ty]
493 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
495 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
496 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
498 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
499 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
500 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
501 -- Interesting: polymorphic recursion would help here.
502 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
503 -- gets the over-specific type (Type -> Type)
506 %************************************************************************
508 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
510 %************************************************************************
512 The tuple types are definitely magic, because they form an infinite
517 They have a special family of type constructors, of type @TyCon@
518 These contain the tycon arity, but don't require a Unique.
521 They have a special family of constructors, of type
522 @Id@. Again these contain their arity but don't need a Unique.
525 There should be a magic way of generating the info tables and
526 entry code for all tuples.
528 But at the moment we just compile a Haskell source
529 file\srcloc{lib/prelude/...} containing declarations like:
532 data Tuple2 a b = Tup2 a b
533 data Tuple3 a b c = Tup3 a b c
534 data Tuple4 a b c d = Tup4 a b c d
537 The print-names associated with the magic @Id@s for tuple constructors
538 ``just happen'' to be the same as those generated by these
542 The instance environment should have a magic way to know
543 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
544 so on. \ToDo{Not implemented yet.}
547 There should also be a way to generate the appropriate code for each
548 of these instances, but (like the info tables and entry code) it is
549 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
553 mkTupleTy :: Boxity -> Int -> [Type] -> Type
554 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
556 unitTy = mkTupleTy Boxed 0 []