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 False -- Not in GADT syntax
216 pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon
217 pcDataCon = pcDataConWithFixity False
219 pcDataConWithFixity :: Bool -> Name -> [TyVar] -> [Type] -> TyCon -> DataCon
220 -- The Name should be in the DataName name space; it's the name
221 -- of the DataCon itself.
223 -- The unique is the first of two free uniques;
224 -- the first is used for the datacon itself,
225 -- the second is used for the "worker name"
227 pcDataConWithFixity declared_infix dc_name tyvars arg_tys tycon
230 data_con = mkDataCon dc_name declared_infix
231 (map (const HsNoBang) arg_tys)
232 [] -- No labelled fields
234 [] -- No existential type variables
235 [] -- No equality spec
237 arg_tys (mkTyConApp tycon (mkTyVarTys tyvars))
239 [] -- No stupid theta
240 (mkDataConIds bogus_wrap_name wrk_name data_con)
243 modu = ASSERT( isExternalName dc_name )
245 wrk_occ = mkDataConWorkerOcc (nameOccName dc_name)
246 wrk_key = incrUnique (nameUnique dc_name)
247 wrk_name = mkWiredInName modu wrk_occ wrk_key
248 (AnId (dataConWorkId data_con)) UserSyntax
249 bogus_wrap_name = pprPanic "Wired-in data wrapper id" (ppr dc_name)
250 -- Wired-in types are too simple to need wrappers
254 %************************************************************************
256 \subsection[TysWiredIn-tuples]{The tuple types}
258 %************************************************************************
261 tupleTyCon :: Boxity -> Arity -> TyCon
262 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
263 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
264 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
266 tupleCon :: Boxity -> Arity -> DataCon
267 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
268 tupleCon Boxed i = snd (boxedTupleArr ! i)
269 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
271 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
272 boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]]
273 unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]]
275 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
276 mk_tuple boxity arity = (tycon, tuple_con)
278 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity
279 modu = mkTupleModule boxity arity
280 tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
281 (ATyCon tycon) BuiltInSyntax
282 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
283 res_kind | isBoxed boxity = liftedTypeKind
284 | otherwise = ubxTupleKind
286 tyvars | isBoxed boxity = take arity alphaTyVars
287 | otherwise = take arity openAlphaTyVars
289 tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
290 tyvar_tys = mkTyVarTys tyvars
291 dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
292 (ADataCon tuple_con) BuiltInSyntax
293 tc_uniq = mkTupleTyConUnique boxity arity
294 dc_uniq = mkTupleDataConUnique boxity arity
297 unitTyCon = tupleTyCon Boxed 0
298 unitDataCon :: DataCon
299 unitDataCon = head (tyConDataCons unitTyCon)
301 unitDataConId = dataConWorkId unitDataCon
304 pairTyCon = tupleTyCon Boxed 2
306 unboxedSingletonTyCon :: TyCon
307 unboxedSingletonTyCon = tupleTyCon Unboxed 1
308 unboxedSingletonDataCon :: DataCon
309 unboxedSingletonDataCon = tupleCon Unboxed 1
311 unboxedPairTyCon :: TyCon
312 unboxedPairTyCon = tupleTyCon Unboxed 2
313 unboxedPairDataCon :: DataCon
314 unboxedPairDataCon = tupleCon Unboxed 2
318 %************************************************************************
320 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
322 %************************************************************************
326 charTy = mkTyConTy charTyCon
329 charTyCon = pcNonRecDataTyCon charTyConName [] [charDataCon]
330 charDataCon :: DataCon
331 charDataCon = pcDataCon charDataConName [] [charPrimTy] charTyCon
334 stringTy = mkListTy charTy -- convenience only
339 intTy = mkTyConTy intTyCon
342 intTyCon = pcNonRecDataTyCon intTyConName [] [intDataCon]
343 intDataCon :: DataCon
344 intDataCon = pcDataCon intDataConName [] [intPrimTy] intTyCon
349 wordTy = mkTyConTy wordTyCon
352 wordTyCon = pcNonRecDataTyCon wordTyConName [] [wordDataCon]
353 wordDataCon :: DataCon
354 wordDataCon = pcDataCon wordDataConName [] [wordPrimTy] wordTyCon
359 floatTy = mkTyConTy floatTyCon
362 floatTyCon = pcNonRecDataTyCon floatTyConName [] [floatDataCon]
363 floatDataCon :: DataCon
364 floatDataCon = pcDataCon floatDataConName [] [floatPrimTy] floatTyCon
369 doubleTy = mkTyConTy doubleTyCon
372 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [doubleDataCon]
374 doubleDataCon :: DataCon
375 doubleDataCon = pcDataCon doubleDataConName [] [doublePrimTy] doubleTyCon
379 %************************************************************************
381 \subsection[TysWiredIn-Bool]{The @Bool@ type}
383 %************************************************************************
385 An ordinary enumeration type, but deeply wired in. There are no
386 magical operations on @Bool@ (just the regular Prelude code).
388 {\em BEGIN IDLE SPECULATION BY SIMON}
390 This is not the only way to encode @Bool@. A more obvious coding makes
391 @Bool@ just a boxed up version of @Bool#@, like this:
394 data Bool = MkBool Bool#
397 Unfortunately, this doesn't correspond to what the Report says @Bool@
398 looks like! Furthermore, we get slightly less efficient code (I
399 think) with this coding. @gtInt@ would look like this:
402 gtInt :: Int -> Int -> Bool
403 gtInt x y = case x of I# x# ->
405 case (gtIntPrim x# y#) of
409 Notice that the result of the @gtIntPrim@ comparison has to be turned
410 into an integer (here called @b#@), and returned in a @MkBool@ box.
412 The @if@ expression would compile to this:
415 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
418 I think this code is a little less efficient than the previous code,
419 but I'm not certain. At all events, corresponding with the Report is
420 important. The interesting thing is that the language is expressive
421 enough to describe more than one alternative; and that a type doesn't
422 necessarily need to be a straightforwardly boxed version of its
423 primitive counterpart.
425 {\em END IDLE SPECULATION BY SIMON}
429 boolTy = mkTyConTy boolTyCon
432 boolTyCon = pcTyCon True NonRecursive boolTyConName
433 [] [falseDataCon, trueDataCon]
435 falseDataCon, trueDataCon :: DataCon
436 falseDataCon = pcDataCon falseDataConName [] [] boolTyCon
437 trueDataCon = pcDataCon trueDataConName [] [] boolTyCon
439 falseDataConId, trueDataConId :: Id
440 falseDataConId = dataConWorkId falseDataCon
441 trueDataConId = dataConWorkId trueDataCon
444 %************************************************************************
446 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
448 %************************************************************************
450 Special syntax, deeply wired in, but otherwise an ordinary algebraic
453 data [] a = [] | a : (List a)
455 data (,) a b = (,,) a b
460 mkListTy :: Type -> Type
461 mkListTy ty = mkTyConApp listTyCon [ty]
464 listTyCon = pcRecDataTyCon listTyConName alpha_tyvar [nilDataCon, consDataCon]
466 nilDataCon :: DataCon
467 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] listTyCon
469 consDataCon :: DataCon
470 consDataCon = pcDataConWithFixity True {- Declared infix -}
472 alpha_tyvar [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
473 -- Interesting: polymorphic recursion would help here.
474 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
475 -- gets the over-specific type (Type -> Type)
478 %************************************************************************
480 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
482 %************************************************************************
484 The tuple types are definitely magic, because they form an infinite
489 They have a special family of type constructors, of type @TyCon@
490 These contain the tycon arity, but don't require a Unique.
493 They have a special family of constructors, of type
494 @Id@. Again these contain their arity but don't need a Unique.
497 There should be a magic way of generating the info tables and
498 entry code for all tuples.
500 But at the moment we just compile a Haskell source
501 file\srcloc{lib/prelude/...} containing declarations like:
504 data Tuple2 a b = Tup2 a b
505 data Tuple3 a b c = Tup3 a b c
506 data Tuple4 a b c d = Tup4 a b c d
509 The print-names associated with the magic @Id@s for tuple constructors
510 ``just happen'' to be the same as those generated by these
514 The instance environment should have a magic way to know
515 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
516 so on. \ToDo{Not implemented yet.}
519 There should also be a way to generate the appropriate code for each
520 of these instances, but (like the info tables and entry code) it is
521 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
525 mkTupleTy :: Boxity -> [Type] -> Type
526 -- Special case for *boxed* 1-tuples, which are represented by the type itself
527 mkTupleTy boxity [ty] | Boxed <- boxity = ty
528 mkTupleTy boxity tys = mkTyConApp (tupleTyCon boxity (length tys)) tys
530 -- | Build the type of a small tuple that holds the specified type of thing
531 mkBoxedTupleTy :: [Type] -> Type
532 mkBoxedTupleTy tys = mkTupleTy Boxed tys
535 unitTy = mkTupleTy Boxed []
538 %************************************************************************
540 \subsection[TysWiredIn-PArr]{The @[::]@ type}
542 %************************************************************************
544 Special syntax for parallel arrays needs some wired in definitions.
547 -- | Construct a type representing the application of the parallel array constructor
548 mkPArrTy :: Type -> Type
549 mkPArrTy ty = mkTyConApp parrTyCon [ty]
551 -- | Represents the type constructor of parallel arrays
553 -- * This must match the definition in @PrelPArr@
555 -- NB: Although the constructor is given here, it will not be accessible in
556 -- user code as it is not in the environment of any compiled module except
560 parrTyCon = pcNonRecDataTyCon parrTyConName alpha_tyvar [parrDataCon]
562 parrDataCon :: DataCon
563 parrDataCon = pcDataCon
565 alpha_tyvar -- forall'ed type variables
566 [intPrimTy, -- 1st argument: Int#
567 mkTyConApp -- 2nd argument: Array# a
572 -- | Check whether a type constructor is the constructor for parallel arrays
573 isPArrTyCon :: TyCon -> Bool
574 isPArrTyCon tc = tyConName tc == parrTyConName
576 -- | Fake array constructors
578 -- * These constructors are never really used to represent array values;
579 -- however, they are very convenient during desugaring (and, in particular,
580 -- in the pattern matching compiler) to treat array pattern just like
581 -- yet another constructor pattern
583 parrFakeCon :: Arity -> DataCon
584 parrFakeCon i | i > mAX_TUPLE_SIZE = mkPArrFakeCon i -- build one specially
585 parrFakeCon i = parrFakeConArr!i
587 -- pre-defined set of constructors
589 parrFakeConArr :: Array Int DataCon
590 parrFakeConArr = array (0, mAX_TUPLE_SIZE) [(i, mkPArrFakeCon i)
591 | i <- [0..mAX_TUPLE_SIZE]]
593 -- build a fake parallel array constructor for the given arity
595 mkPArrFakeCon :: Int -> DataCon
596 mkPArrFakeCon arity = data_con
598 data_con = pcDataCon name [tyvar] tyvarTys parrTyCon
599 tyvar = head alphaTyVars
600 tyvarTys = replicate arity $ mkTyVarTy tyvar
601 nameStr = mkFastString ("MkPArr" ++ show arity)
602 name = mkWiredInName gHC_PARR' (mkDataOccFS nameStr) unique
603 (ADataCon data_con) UserSyntax
604 unique = mkPArrDataConUnique arity
606 -- | Checks whether a data constructor is a fake constructor for parallel arrays
607 isPArrFakeCon :: DataCon -> Bool
608 isPArrFakeCon dcon = dcon == parrFakeCon (dataConSourceArity dcon)