2 % (c) The GRASP Project, Glasgow University, 1994-1998
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
7 -- | This module is about types that can be defined in Haskell, but which
8 -- must be wired into the compiler nonetheless. C.f module TysPrim
10 -- * All wired in things
14 boolTy, boolTyCon, boolTyCon_RDR, boolTyConName,
15 trueDataCon, trueDataConId, true_RDR,
16 falseDataCon, falseDataConId, false_RDR,
19 charTyCon, charDataCon, charTyCon_RDR,
20 charTy, stringTy, charTyConName,
23 doubleTyCon, doubleDataCon, doubleTy, doubleTyConName,
26 floatTyCon, floatDataCon, floatTy, floatTyConName,
29 intTyCon, intDataCon, intTyCon_RDR, intDataCon_RDR, intTyConName,
33 wordTyCon, wordDataCon, wordTyConName, wordTy,
36 listTyCon, nilDataCon, consDataCon,
37 listTyCon_RDR, consDataCon_RDR, listTyConName,
41 mkTupleTy, mkBoxedTupleTy,
43 unitTyCon, unitDataCon, unitDataConId, pairTyCon,
44 unboxedSingletonTyCon, unboxedSingletonDataCon,
45 unboxedPairTyCon, unboxedPairDataCon,
52 parrTyCon, parrFakeCon, isPArrTyCon, isPArrFakeCon,
53 parrTyCon_RDR, parrTyConName
56 #include "HsVersions.h"
58 import {-# SOURCE #-} MkId( mkDataConIds )
65 import Constants ( mAX_TUPLE_SIZE )
66 import Module ( Module )
69 import DataCon ( DataCon, mkDataCon, dataConWorkId, dataConSourceArity )
71 import TyCon ( TyCon, AlgTyConRhs(DataTyCon), tyConDataCons,
72 mkTupleTyCon, mkAlgTyCon, tyConName,
73 TyConParent(NoParentTyCon) )
75 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed, HsBang(..) )
77 import Type ( Type, mkTyConTy, mkTyConApp, mkTyVarTy, mkTyVarTys,
79 import Coercion ( unsafeCoercionTyCon, symCoercionTyCon,
80 transCoercionTyCon, leftCoercionTyCon,
81 rightCoercionTyCon, instCoercionTyCon )
82 import TypeRep ( mkArrowKinds, liftedTypeKind, ubxTupleKind )
83 import Unique ( incrUnique, mkTupleTyConUnique,
84 mkTupleDataConUnique, mkPArrDataConUnique )
89 alpha_tyvar :: [TyVar]
90 alpha_tyvar = [alphaTyVar]
97 %************************************************************************
99 \subsection{Wired in type constructors}
101 %************************************************************************
103 If you change which things are wired in, make sure you change their
104 names in PrelNames, so they use wTcQual, wDataQual, etc
107 wiredInTyCons :: [TyCon] -- Excludes tuples
108 -- This list is used only to define PrelInfo.wiredInThings
110 -- It does not need to include kind constructors, because
111 -- all that wiredInThings does is to initialise the Name table,
112 -- and kind constructors don't appear in source code.
114 wiredInTyCons = [ unitTyCon -- Not treated like other tuples, because
115 -- it's defined in GHC.Base, and there's only
116 -- one of it. We put it in wiredInTyCons so
117 -- that it'll pre-populate the name cache, so
118 -- the special case in lookupOrigNameCache
119 -- doesn't need to look out for it
127 , unsafeCoercionTyCon
137 mkWiredInTyConName :: BuiltInSyntax -> Module -> FastString -> Unique -> TyCon -> Name
138 mkWiredInTyConName built_in modu fs unique tycon
139 = mkWiredInName modu (mkTcOccFS fs) unique
140 (ATyCon tycon) -- Relevant TyCon
143 mkWiredInDataConName :: BuiltInSyntax -> Module -> FastString -> Unique -> DataCon -> Name
144 mkWiredInDataConName built_in modu fs unique datacon
145 = mkWiredInName modu (mkDataOccFS fs) unique
146 (ADataCon datacon) -- Relevant DataCon
149 charTyConName, charDataConName, intTyConName, intDataConName :: Name
150 charTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Char") charTyConKey charTyCon
151 charDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "C#") charDataConKey charDataCon
152 intTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Int") intTyConKey intTyCon
153 intDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "I#") intDataConKey intDataCon
155 boolTyConName, falseDataConName, trueDataConName :: Name
156 boolTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Bool") boolTyConKey boolTyCon
157 falseDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "False") falseDataConKey falseDataCon
158 trueDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "True") trueDataConKey trueDataCon
160 listTyConName, nilDataConName, consDataConName :: Name
161 listTyConName = mkWiredInTyConName BuiltInSyntax gHC_TYPES (fsLit "[]") listTyConKey listTyCon
162 nilDataConName = mkWiredInDataConName BuiltInSyntax gHC_TYPES (fsLit "[]") nilDataConKey nilDataCon
163 consDataConName = mkWiredInDataConName BuiltInSyntax gHC_TYPES (fsLit ":") consDataConKey consDataCon
165 floatTyConName, floatDataConName, doubleTyConName, doubleDataConName :: Name
166 floatTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Float") floatTyConKey floatTyCon
167 floatDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "F#") floatDataConKey floatDataCon
168 doubleTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Double") doubleTyConKey doubleTyCon
169 doubleDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "D#") doubleDataConKey doubleDataCon
171 parrTyConName, parrDataConName :: Name
172 parrTyConName = mkWiredInTyConName BuiltInSyntax
173 gHC_PARR' (fsLit "[::]") parrTyConKey parrTyCon
174 parrDataConName = mkWiredInDataConName UserSyntax
175 gHC_PARR' (fsLit "PArr") parrDataConKey parrDataCon
177 boolTyCon_RDR, false_RDR, true_RDR, intTyCon_RDR, charTyCon_RDR,
178 intDataCon_RDR, listTyCon_RDR, consDataCon_RDR, parrTyCon_RDR:: RdrName
179 boolTyCon_RDR = nameRdrName boolTyConName
180 false_RDR = nameRdrName falseDataConName
181 true_RDR = nameRdrName trueDataConName
182 intTyCon_RDR = nameRdrName intTyConName
183 charTyCon_RDR = nameRdrName charTyConName
184 intDataCon_RDR = nameRdrName intDataConName
185 listTyCon_RDR = nameRdrName listTyConName
186 consDataCon_RDR = nameRdrName consDataConName
187 parrTyCon_RDR = nameRdrName parrTyConName
191 %************************************************************************
193 \subsection{mkWiredInTyCon}
195 %************************************************************************
198 pcNonRecDataTyCon :: Name -> [TyVar] -> [DataCon] -> TyCon
199 pcNonRecDataTyCon = pcTyCon False NonRecursive
200 pcRecDataTyCon :: Name -> [TyVar] -> [DataCon] -> TyCon
201 pcRecDataTyCon = pcTyCon False Recursive
203 pcTyCon :: Bool -> RecFlag -> Name -> [TyVar] -> [DataCon] -> TyCon
204 pcTyCon is_enum is_rec name tyvars cons
207 tycon = mkAlgTyCon name
208 (mkArrowKinds (map tyVarKind tyvars) liftedTypeKind)
210 [] -- No stupid theta
211 (DataTyCon cons is_enum)
214 True -- All the wired-in tycons have generics
215 False -- Not in GADT syntax
217 pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon
218 pcDataCon = pcDataConWithFixity False
220 pcDataConWithFixity :: Bool -> Name -> [TyVar] -> [Type] -> TyCon -> DataCon
221 -- The Name should be in the DataName name space; it's the name
222 -- of the DataCon itself.
224 -- The unique is the first of two free uniques;
225 -- the first is used for the datacon itself,
226 -- the second is used for the "worker name"
228 pcDataConWithFixity declared_infix dc_name tyvars arg_tys tycon
231 data_con = mkDataCon dc_name declared_infix
232 (map (const HsNoBang) arg_tys)
233 [] -- No labelled fields
235 [] -- No existential type variables
236 [] -- No equality spec
238 arg_tys (mkTyConApp tycon (mkTyVarTys tyvars))
240 [] -- No stupid theta
241 (mkDataConIds bogus_wrap_name wrk_name data_con)
244 modu = ASSERT( isExternalName dc_name )
246 wrk_occ = mkDataConWorkerOcc (nameOccName dc_name)
247 wrk_key = incrUnique (nameUnique dc_name)
248 wrk_name = mkWiredInName modu wrk_occ wrk_key
249 (AnId (dataConWorkId data_con)) UserSyntax
250 bogus_wrap_name = pprPanic "Wired-in data wrapper id" (ppr dc_name)
251 -- Wired-in types are too simple to need wrappers
255 %************************************************************************
257 \subsection[TysWiredIn-tuples]{The tuple types}
259 %************************************************************************
262 tupleTyCon :: Boxity -> Arity -> TyCon
263 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
264 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
265 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
267 tupleCon :: Boxity -> Arity -> DataCon
268 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
269 tupleCon Boxed i = snd (boxedTupleArr ! i)
270 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
272 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
273 boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]]
274 unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]]
276 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
277 mk_tuple boxity arity = (tycon, tuple_con)
279 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
280 modu = mkTupleModule boxity arity
281 tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
282 (ATyCon tycon) BuiltInSyntax
283 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
284 res_kind | isBoxed boxity = liftedTypeKind
285 | otherwise = ubxTupleKind
287 tyvars | isBoxed boxity = take arity alphaTyVars
288 | otherwise = take arity openAlphaTyVars
290 tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
291 tyvar_tys = mkTyVarTys tyvars
292 dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
293 (ADataCon tuple_con) BuiltInSyntax
294 tc_uniq = mkTupleTyConUnique boxity arity
295 dc_uniq = mkTupleDataConUnique boxity arity
296 gen_info = True -- Tuples all have generics..
297 -- hmm: that's a *lot* of code
300 unitTyCon = tupleTyCon Boxed 0
301 unitDataCon :: DataCon
302 unitDataCon = head (tyConDataCons unitTyCon)
304 unitDataConId = dataConWorkId unitDataCon
307 pairTyCon = tupleTyCon Boxed 2
309 unboxedSingletonTyCon :: TyCon
310 unboxedSingletonTyCon = tupleTyCon Unboxed 1
311 unboxedSingletonDataCon :: DataCon
312 unboxedSingletonDataCon = tupleCon Unboxed 1
314 unboxedPairTyCon :: TyCon
315 unboxedPairTyCon = tupleTyCon Unboxed 2
316 unboxedPairDataCon :: DataCon
317 unboxedPairDataCon = tupleCon Unboxed 2
321 %************************************************************************
323 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
325 %************************************************************************
329 charTy = mkTyConTy charTyCon
332 charTyCon = pcNonRecDataTyCon charTyConName [] [charDataCon]
333 charDataCon :: DataCon
334 charDataCon = pcDataCon charDataConName [] [charPrimTy] charTyCon
337 stringTy = mkListTy charTy -- convenience only
342 intTy = mkTyConTy intTyCon
345 intTyCon = pcNonRecDataTyCon intTyConName [] [intDataCon]
346 intDataCon :: DataCon
347 intDataCon = pcDataCon intDataConName [] [intPrimTy] intTyCon
352 wordTy = mkTyConTy wordTyCon
355 wordTyCon = pcNonRecDataTyCon wordTyConName [] [wordDataCon]
356 wordDataCon :: DataCon
357 wordDataCon = pcDataCon wordDataConName [] [wordPrimTy] wordTyCon
362 floatTy = mkTyConTy floatTyCon
365 floatTyCon = pcNonRecDataTyCon floatTyConName [] [floatDataCon]
366 floatDataCon :: DataCon
367 floatDataCon = pcDataCon floatDataConName [] [floatPrimTy] floatTyCon
372 doubleTy = mkTyConTy doubleTyCon
375 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [doubleDataCon]
377 doubleDataCon :: DataCon
378 doubleDataCon = pcDataCon doubleDataConName [] [doublePrimTy] doubleTyCon
382 %************************************************************************
384 \subsection[TysWiredIn-Bool]{The @Bool@ type}
386 %************************************************************************
388 An ordinary enumeration type, but deeply wired in. There are no
389 magical operations on @Bool@ (just the regular Prelude code).
391 {\em BEGIN IDLE SPECULATION BY SIMON}
393 This is not the only way to encode @Bool@. A more obvious coding makes
394 @Bool@ just a boxed up version of @Bool#@, like this:
397 data Bool = MkBool Bool#
400 Unfortunately, this doesn't correspond to what the Report says @Bool@
401 looks like! Furthermore, we get slightly less efficient code (I
402 think) with this coding. @gtInt@ would look like this:
405 gtInt :: Int -> Int -> Bool
406 gtInt x y = case x of I# x# ->
408 case (gtIntPrim x# y#) of
412 Notice that the result of the @gtIntPrim@ comparison has to be turned
413 into an integer (here called @b#@), and returned in a @MkBool@ box.
415 The @if@ expression would compile to this:
418 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
421 I think this code is a little less efficient than the previous code,
422 but I'm not certain. At all events, corresponding with the Report is
423 important. The interesting thing is that the language is expressive
424 enough to describe more than one alternative; and that a type doesn't
425 necessarily need to be a straightforwardly boxed version of its
426 primitive counterpart.
428 {\em END IDLE SPECULATION BY SIMON}
432 boolTy = mkTyConTy boolTyCon
435 boolTyCon = pcTyCon True NonRecursive boolTyConName
436 [] [falseDataCon, trueDataCon]
438 falseDataCon, trueDataCon :: DataCon
439 falseDataCon = pcDataCon falseDataConName [] [] boolTyCon
440 trueDataCon = pcDataCon trueDataConName [] [] boolTyCon
442 falseDataConId, trueDataConId :: Id
443 falseDataConId = dataConWorkId falseDataCon
444 trueDataConId = dataConWorkId trueDataCon
447 %************************************************************************
449 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
451 %************************************************************************
453 Special syntax, deeply wired in, but otherwise an ordinary algebraic
456 data [] a = [] | a : (List a)
458 data (,) a b = (,,) a b
463 mkListTy :: Type -> Type
464 mkListTy ty = mkTyConApp listTyCon [ty]
467 listTyCon = pcRecDataTyCon listTyConName alpha_tyvar [nilDataCon, consDataCon]
469 nilDataCon :: DataCon
470 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] listTyCon
472 consDataCon :: DataCon
473 consDataCon = pcDataConWithFixity True {- Declared infix -}
475 alpha_tyvar [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
476 -- Interesting: polymorphic recursion would help here.
477 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
478 -- gets the over-specific type (Type -> Type)
481 %************************************************************************
483 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
485 %************************************************************************
487 The tuple types are definitely magic, because they form an infinite
492 They have a special family of type constructors, of type @TyCon@
493 These contain the tycon arity, but don't require a Unique.
496 They have a special family of constructors, of type
497 @Id@. Again these contain their arity but don't need a Unique.
500 There should be a magic way of generating the info tables and
501 entry code for all tuples.
503 But at the moment we just compile a Haskell source
504 file\srcloc{lib/prelude/...} containing declarations like:
507 data Tuple2 a b = Tup2 a b
508 data Tuple3 a b c = Tup3 a b c
509 data Tuple4 a b c d = Tup4 a b c d
512 The print-names associated with the magic @Id@s for tuple constructors
513 ``just happen'' to be the same as those generated by these
517 The instance environment should have a magic way to know
518 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
519 so on. \ToDo{Not implemented yet.}
522 There should also be a way to generate the appropriate code for each
523 of these instances, but (like the info tables and entry code) it is
524 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
528 mkTupleTy :: Boxity -> [Type] -> Type
529 -- Special case for *boxed* 1-tuples, which are represented by the type itself
530 mkTupleTy boxity [ty] | Boxed <- boxity = ty
531 mkTupleTy boxity tys = mkTyConApp (tupleTyCon boxity (length tys)) tys
533 -- | Build the type of a small tuple that holds the specified type of thing
534 mkBoxedTupleTy :: [Type] -> Type
535 mkBoxedTupleTy tys = mkTupleTy Boxed tys
538 unitTy = mkTupleTy Boxed []
541 %************************************************************************
543 \subsection[TysWiredIn-PArr]{The @[::]@ type}
545 %************************************************************************
547 Special syntax for parallel arrays needs some wired in definitions.
550 -- | Construct a type representing the application of the parallel array constructor
551 mkPArrTy :: Type -> Type
552 mkPArrTy ty = mkTyConApp parrTyCon [ty]
554 -- | Represents the type constructor of parallel arrays
556 -- * This must match the definition in @PrelPArr@
558 -- NB: Although the constructor is given here, it will not be accessible in
559 -- user code as it is not in the environment of any compiled module except
563 parrTyCon = pcNonRecDataTyCon parrTyConName alpha_tyvar [parrDataCon]
565 parrDataCon :: DataCon
566 parrDataCon = pcDataCon
568 alpha_tyvar -- forall'ed type variables
569 [intPrimTy, -- 1st argument: Int#
570 mkTyConApp -- 2nd argument: Array# a
575 -- | Check whether a type constructor is the constructor for parallel arrays
576 isPArrTyCon :: TyCon -> Bool
577 isPArrTyCon tc = tyConName tc == parrTyConName
579 -- | Fake array constructors
581 -- * These constructors are never really used to represent array values;
582 -- however, they are very convenient during desugaring (and, in particular,
583 -- in the pattern matching compiler) to treat array pattern just like
584 -- yet another constructor pattern
586 parrFakeCon :: Arity -> DataCon
587 parrFakeCon i | i > mAX_TUPLE_SIZE = mkPArrFakeCon i -- build one specially
588 parrFakeCon i = parrFakeConArr!i
590 -- pre-defined set of constructors
592 parrFakeConArr :: Array Int DataCon
593 parrFakeConArr = array (0, mAX_TUPLE_SIZE) [(i, mkPArrFakeCon i)
594 | i <- [0..mAX_TUPLE_SIZE]]
596 -- build a fake parallel array constructor for the given arity
598 mkPArrFakeCon :: Int -> DataCon
599 mkPArrFakeCon arity = data_con
601 data_con = pcDataCon name [tyvar] tyvarTys parrTyCon
602 tyvar = head alphaTyVars
603 tyvarTys = replicate arity $ mkTyVarTy tyvar
604 nameStr = mkFastString ("MkPArr" ++ show arity)
605 name = mkWiredInName gHC_PARR' (mkDataOccFS nameStr) unique
606 (ADataCon data_con) UserSyntax
607 unique = mkPArrDataConUnique arity
609 -- | Checks whether a data constructor is a fake constructor for parallel arrays
610 isPArrFakeCon :: DataCon -> Bool
611 isPArrFakeCon dcon = dcon == parrFakeCon (dataConSourceArity dcon)