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, NewOrData(..), RecFlag(..), Boxity(..), isBoxed )
91 import Type ( Type, mkTyConTy, mkTyConApp, mkSigmaTy, mkTyVarTys,
92 mkArrowKinds, boxedTypeKind, unboxedTypeKind,
94 splitTyConApp_maybe, repType,
95 TauType, ClassContext )
96 import PrimRep ( PrimRep(..) )
98 import CmdLineOpts ( opt_GlasgowExts )
100 import Panic ( panic )
103 alpha_tyvar = [alphaTyVar]
105 alpha_beta_tyvars = [alphaTyVar, betaTyVar]
107 pcRecDataTyCon, pcNonRecDataTyCon
108 :: Unique{-TyConKey-} -> Module -> FAST_STRING
109 -> [TyVar] -> ArgVrcs -> [DataCon] -> TyCon
111 pcRecDataTyCon = pcTyCon DataTyCon Recursive
112 pcNonRecDataTyCon = pcTyCon DataTyCon NonRecursive
114 pcTyCon new_or_data is_rec key mod str tyvars argvrcs cons
117 tycon = mkAlgTyCon name kind
127 name = mkWiredInTyConName key mod str tycon
128 kind = mkArrowKinds (map tyVarKind tyvars) boxedTypeKind
130 pcSynTyCon key mod str kind arity tyvars expansion argvrcs -- this fun never used!
133 tycon = mkSynTyCon name kind arity tyvars expansion argvrcs
134 name = mkWiredInTyConName key mod str tycon
136 pcDataCon :: Unique{-DataConKey-} -> Module -> FAST_STRING
137 -> [TyVar] -> ClassContext -> [TauType] -> TyCon -> DataCon
138 -- The unique is the first of two free uniques;
139 -- the first is used for the datacon itself and the worker;
140 -- the second is used for the wrapper.
141 pcDataCon wrap_key mod str tyvars context arg_tys tycon
144 data_con = mkDataCon wrap_name
145 [ NotMarkedStrict | a <- arg_tys ]
146 [ {- no labelled fields -} ]
147 tyvars context [] [] arg_tys tycon work_id wrap_id
149 work_occ = mkWorkerOcc wrap_occ
150 work_key = incrUnique wrap_key
151 work_name = mkWiredInIdName work_key mod work_occ work_id
152 work_id = mkDataConId work_name data_con
154 wrap_occ = mkSrcOccFS dataName str
155 wrap_name = mkWiredInIdName wrap_key mod wrap_occ wrap_id
156 wrap_id = mkDataConWrapId data_con
160 %************************************************************************
162 \subsection[TysWiredIn-tuples]{The tuple types}
164 %************************************************************************
167 tupleTyCon :: Boxity -> Arity -> TyCon
168 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
169 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
170 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
172 tupleCon :: Boxity -> Arity -> DataCon
173 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
174 tupleCon Boxed i = snd (boxedTupleArr ! i)
175 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
177 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
178 boxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Boxed i) | i <- [0..mAX_TUPLE_SIZE]]
179 unboxedTupleArr = array (0,mAX_TUPLE_SIZE) [(i,mk_tuple Unboxed i) | i <- [0..mAX_TUPLE_SIZE]]
181 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
182 mk_tuple boxity arity = (tycon, tuple_con)
184 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity
185 tc_name = mkWiredInTyConName tc_uniq mod name_str tycon
186 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
187 res_kind | isBoxed boxity = boxedTypeKind
188 | otherwise = unboxedTypeKind
190 tyvars | isBoxed boxity = take arity alphaTyVars
191 | otherwise = take arity openAlphaTyVars
193 tuple_con = pcDataCon dc_uniq mod name_str tyvars [] tyvar_tys tycon
194 tyvar_tys = mkTyVarTys tyvars
195 (mod_name, name_str) = mkTupNameStr boxity arity
196 tc_uniq = mkTupleTyConUnique boxity arity
197 dc_uniq = mkTupleDataConUnique boxity arity
198 mod = mkPrelModule mod_name
200 unitTyCon = tupleTyCon Boxed 0
201 unitDataConId = dataConId (head (tyConDataCons unitTyCon))
203 pairTyCon = tupleTyCon Boxed 2
205 unboxedSingletonTyCon = tupleTyCon Unboxed 1
206 unboxedSingletonDataCon = tupleCon Unboxed 1
208 unboxedPairTyCon = tupleTyCon Unboxed 2
209 unboxedPairDataCon = tupleCon Unboxed 2
212 %************************************************************************
214 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
216 %************************************************************************
219 -- The Void type is represented as a data type with no constructors
220 -- It's a built in type (i.e. there's no way to define it in Haskell;
221 -- the nearest would be
223 -- data Void = -- No constructors!
225 -- ) It's boxed; there is only one value of this
226 -- type, namely "void", whose semantics is just bottom.
228 -- Haskell 98 drops the definition of a Void type, so we just 'simulate'
235 charTy = mkTyConTy charTyCon
237 charTyCon = pcNonRecDataTyCon charTyConKey pREL_BASE SLIT("Char") [] [] [charDataCon]
238 charDataCon = pcDataCon charDataConKey pREL_BASE SLIT("C#") [] [] [charPrimTy] charTyCon
240 stringTy = mkListTy charTy -- convenience only
244 intTy = mkTyConTy intTyCon
246 intTyCon = pcNonRecDataTyCon intTyConKey pREL_BASE SLIT("Int") [] [] [intDataCon]
247 intDataCon = pcDataCon intDataConKey pREL_BASE SLIT("I#") [] [] [intPrimTy] intTyCon
249 isIntTy :: Type -> Bool
250 isIntTy = isTyCon intTyConKey
255 wordTy = mkTyConTy wordTyCon
257 wordTyCon = pcNonRecDataTyCon wordTyConKey pREL_ADDR SLIT("Word") [] [] [wordDataCon]
258 wordDataCon = pcDataCon wordDataConKey pREL_ADDR SLIT("W#") [] [] [wordPrimTy] wordTyCon
262 addrTy = mkTyConTy addrTyCon
264 addrTyCon = pcNonRecDataTyCon addrTyConKey pREL_ADDR SLIT("Addr") [] [] [addrDataCon]
265 addrDataCon = pcDataCon addrDataConKey pREL_ADDR SLIT("A#") [] [] [addrPrimTy] addrTyCon
267 isAddrTy :: Type -> Bool
268 isAddrTy = isTyCon addrTyConKey
272 floatTy = mkTyConTy floatTyCon
274 floatTyCon = pcNonRecDataTyCon floatTyConKey pREL_FLOAT SLIT("Float") [] [] [floatDataCon]
275 floatDataCon = pcDataCon floatDataConKey pREL_FLOAT SLIT("F#") [] [] [floatPrimTy] floatTyCon
277 isFloatTy :: Type -> Bool
278 isFloatTy = isTyCon floatTyConKey
282 doubleTy = mkTyConTy doubleTyCon
284 isDoubleTy :: Type -> Bool
285 isDoubleTy = isTyCon doubleTyConKey
287 doubleTyCon = pcNonRecDataTyCon doubleTyConKey pREL_FLOAT SLIT("Double") [] [] [doubleDataCon]
288 doubleDataCon = pcDataCon doubleDataConKey pREL_FLOAT SLIT("D#") [] [] [doublePrimTy] doubleTyCon
293 = pcNonRecDataTyCon stablePtrTyConKey pREL_STABLE SLIT("StablePtr")
294 alpha_tyvar [(True,False)] [stablePtrDataCon]
297 = pcDataCon stablePtrDataConKey pREL_STABLE SLIT("StablePtr")
298 alpha_tyvar [] [mkStablePtrPrimTy alphaTy] stablePtrTyCon
303 = pcNonRecDataTyCon foreignObjTyConKey pREL_IO_BASE SLIT("ForeignObj")
304 [] [] [foreignObjDataCon]
307 = pcDataCon foreignObjDataConKey pREL_IO_BASE SLIT("ForeignObj")
308 [] [] [foreignObjPrimTy] foreignObjTyCon
310 isForeignObjTy :: Type -> Bool
311 isForeignObjTy = isTyCon foreignObjTyConKey
314 %************************************************************************
316 \subsection[TysWiredIn-Integer]{@Integer@ and its related ``pairing'' types}
318 %************************************************************************
320 @Integer@ and its pals are not really primitive. @Integer@ itself, first:
323 integerTy = mkTyConTy integerTyCon
325 integerTyCon = pcNonRecDataTyCon integerTyConKey pREL_NUM SLIT("Integer")
326 [] [] [smallIntegerDataCon, largeIntegerDataCon]
328 smallIntegerDataCon = pcDataCon smallIntegerDataConKey pREL_NUM SLIT("S#")
329 [] [] [intPrimTy] integerTyCon
330 largeIntegerDataCon = pcDataCon largeIntegerDataConKey pREL_NUM SLIT("J#")
331 [] [] [intPrimTy, byteArrayPrimTy] integerTyCon
334 isIntegerTy :: Type -> Bool
335 isIntegerTy = isTyCon integerTyConKey
339 %************************************************************************
341 \subsection[TysWiredIn-ext-type]{External types}
343 %************************************************************************
345 The compiler's foreign function interface supports the passing of a
346 restricted set of types as arguments and results (the restricting factor
350 isFFIArgumentTy :: Bool -> Type -> Bool
351 -- Checks for valid argument type for a 'foreign import'
352 isFFIArgumentTy is_safe ty = checkRepTyCon (legalOutgoingTyCon is_safe) ty
354 isFFIExternalTy :: Type -> Bool
355 -- Types that are allowed as arguments of a 'foreign export'
356 isFFIExternalTy ty = checkRepTyCon legalIncomingTyCon ty
358 isFFIResultTy :: Type -> Bool
359 -- Types that are allowed as a result of a 'foreign import' or of a 'foreign export'
360 -- Maybe we should distinguish between import and export, but
361 -- here we just choose the more restrictive 'incoming' predicate
362 -- But we allow () as well
363 isFFIResultTy ty = checkRepTyCon (\tc -> tc == unitTyCon || legalIncomingTyCon tc) ty
365 checkRepTyCon :: (TyCon -> Bool) -> Type -> Bool
366 -- look through newtypes
367 checkRepTyCon check_tc ty = checkTyCon check_tc (repType ty)
369 checkTyCon :: (TyCon -> Bool) -> Type -> Bool
370 checkTyCon check_tc ty = case splitTyConApp_maybe ty of
371 Just (tycon, _) -> check_tc tycon
374 isTyCon :: Unique -> Type -> Bool
375 isTyCon uniq ty = checkTyCon (\tc -> uniq == getUnique tc) ty
378 ----------------------------------------------
379 These chaps do the work; they are not exported
380 ----------------------------------------------
383 legalIncomingTyCon :: TyCon -> Bool
384 -- It's illegal to return foreign objects and (mutable)
385 -- bytearrays from a _ccall_ / foreign declaration
386 -- (or be passed them as arguments in foreign exported functions).
387 legalIncomingTyCon tc
388 | getUnique tc `elem` [ foreignObjTyConKey, byteArrayTyConKey, mutableByteArrayTyConKey ]
391 = marshalableTyCon tc
393 legalOutgoingTyCon :: Bool -> TyCon -> Bool
394 -- Checks validity of types going from Haskell -> external world
395 -- The boolean is true for a 'safe' call (when we don't want to
396 -- pass Haskell pointers to the world)
397 legalOutgoingTyCon be_safe tc
398 | be_safe && getUnique tc `elem` [byteArrayTyConKey, mutableByteArrayTyConKey]
401 = marshalableTyCon tc
404 = (opt_GlasgowExts && isUnLiftedTyCon tc)
405 || getUnique tc `elem` [ intTyConKey, int8TyConKey, int16TyConKey, int32TyConKey, int64TyConKey
406 , wordTyConKey, word8TyConKey, word16TyConKey, word32TyConKey, word64TyConKey
407 , floatTyConKey, doubleTyConKey
408 , addrTyConKey, charTyConKey, foreignObjTyConKey
410 , byteArrayTyConKey, mutableByteArrayTyConKey
416 %************************************************************************
418 \subsection[TysWiredIn-Bool]{The @Bool@ type}
420 %************************************************************************
422 An ordinary enumeration type, but deeply wired in. There are no
423 magical operations on @Bool@ (just the regular Prelude code).
425 {\em BEGIN IDLE SPECULATION BY SIMON}
427 This is not the only way to encode @Bool@. A more obvious coding makes
428 @Bool@ just a boxed up version of @Bool#@, like this:
431 data Bool = MkBool Bool#
434 Unfortunately, this doesn't correspond to what the Report says @Bool@
435 looks like! Furthermore, we get slightly less efficient code (I
436 think) with this coding. @gtInt@ would look like this:
439 gtInt :: Int -> Int -> Bool
440 gtInt x y = case x of I# x# ->
442 case (gtIntPrim x# y#) of
446 Notice that the result of the @gtIntPrim@ comparison has to be turned
447 into an integer (here called @b#@), and returned in a @MkBool@ box.
449 The @if@ expression would compile to this:
452 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
455 I think this code is a little less efficient than the previous code,
456 but I'm not certain. At all events, corresponding with the Report is
457 important. The interesting thing is that the language is expressive
458 enough to describe more than one alternative; and that a type doesn't
459 necessarily need to be a straightforwardly boxed version of its
460 primitive counterpart.
462 {\em END IDLE SPECULATION BY SIMON}
465 boolTy = mkTyConTy boolTyCon
467 boolTyCon = pcTyCon EnumTyCon NonRecursive boolTyConKey
468 pREL_BASE SLIT("Bool") [] [] [falseDataCon, trueDataCon]
470 falseDataCon = pcDataCon falseDataConKey pREL_BASE SLIT("False") [] [] [] boolTyCon
471 trueDataCon = pcDataCon trueDataConKey pREL_BASE SLIT("True") [] [] [] boolTyCon
473 falseDataConId = dataConId falseDataCon
474 trueDataConId = dataConId trueDataCon
477 %************************************************************************
479 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
481 %************************************************************************
483 Special syntax, deeply wired in, but otherwise an ordinary algebraic
486 data [] a = [] | a : (List a)
488 data (,) a b = (,,) a b
493 mkListTy :: Type -> Type
494 mkListTy ty = mkTyConApp listTyCon [ty]
496 alphaListTy = mkSigmaTy alpha_tyvar [] (mkTyConApp listTyCon alpha_ty)
498 listTyCon = pcRecDataTyCon listTyConKey pREL_BASE SLIT("[]")
499 alpha_tyvar [(True,False)] [nilDataCon, consDataCon]
501 nilDataCon = pcDataCon nilDataConKey pREL_BASE SLIT("[]") alpha_tyvar [] [] listTyCon
502 consDataCon = pcDataCon consDataConKey pREL_BASE SLIT(":")
503 alpha_tyvar [] [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
504 -- Interesting: polymorphic recursion would help here.
505 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
506 -- gets the over-specific type (Type -> Type)
509 %************************************************************************
511 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
513 %************************************************************************
515 The tuple types are definitely magic, because they form an infinite
520 They have a special family of type constructors, of type @TyCon@
521 These contain the tycon arity, but don't require a Unique.
524 They have a special family of constructors, of type
525 @Id@. Again these contain their arity but don't need a Unique.
528 There should be a magic way of generating the info tables and
529 entry code for all tuples.
531 But at the moment we just compile a Haskell source
532 file\srcloc{lib/prelude/...} containing declarations like:
535 data Tuple2 a b = Tup2 a b
536 data Tuple3 a b c = Tup3 a b c
537 data Tuple4 a b c d = Tup4 a b c d
540 The print-names associated with the magic @Id@s for tuple constructors
541 ``just happen'' to be the same as those generated by these
545 The instance environment should have a magic way to know
546 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
547 so on. \ToDo{Not implemented yet.}
550 There should also be a way to generate the appropriate code for each
551 of these instances, but (like the info tables and entry code) it is
552 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
556 mkTupleTy :: Boxity -> Int -> [Type] -> Type
557 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
559 unitTy = mkTupleTy Boxed 0 []