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 gHC_PARR (fsLit "[::]") parrTyConKey parrTyCon
173 parrDataConName = mkWiredInDataConName UserSyntax gHC_PARR (fsLit "PArr") parrDataConKey parrDataCon
175 boolTyCon_RDR, false_RDR, true_RDR, intTyCon_RDR, charTyCon_RDR,
176 intDataCon_RDR, listTyCon_RDR, consDataCon_RDR, parrTyCon_RDR:: RdrName
177 boolTyCon_RDR = nameRdrName boolTyConName
178 false_RDR = nameRdrName falseDataConName
179 true_RDR = nameRdrName trueDataConName
180 intTyCon_RDR = nameRdrName intTyConName
181 charTyCon_RDR = nameRdrName charTyConName
182 intDataCon_RDR = nameRdrName intDataConName
183 listTyCon_RDR = nameRdrName listTyConName
184 consDataCon_RDR = nameRdrName consDataConName
185 parrTyCon_RDR = nameRdrName parrTyConName
189 %************************************************************************
191 \subsection{mkWiredInTyCon}
193 %************************************************************************
196 pcNonRecDataTyCon :: Name -> [TyVar] -> [DataCon] -> TyCon
197 pcNonRecDataTyCon = pcTyCon False NonRecursive
198 pcRecDataTyCon :: Name -> [TyVar] -> [DataCon] -> TyCon
199 pcRecDataTyCon = pcTyCon False Recursive
201 pcTyCon :: Bool -> RecFlag -> Name -> [TyVar] -> [DataCon] -> TyCon
202 pcTyCon is_enum is_rec name tyvars cons
205 tycon = mkAlgTyCon name
206 (mkArrowKinds (map tyVarKind tyvars) liftedTypeKind)
208 [] -- No stupid theta
209 (DataTyCon cons is_enum)
212 True -- All the wired-in tycons have generics
213 False -- Not in GADT syntax
215 pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon
216 pcDataCon = pcDataConWithFixity False
218 pcDataConWithFixity :: Bool -> Name -> [TyVar] -> [Type] -> TyCon -> DataCon
219 -- The Name should be in the DataName name space; it's the name
220 -- of the DataCon itself.
222 -- The unique is the first of two free uniques;
223 -- the first is used for the datacon itself,
224 -- the second is used for the "worker name"
226 pcDataConWithFixity declared_infix dc_name tyvars arg_tys tycon
229 data_con = mkDataCon dc_name declared_infix
230 (map (const HsNoBang) arg_tys)
231 [] -- No labelled fields
233 [] -- No existential type variables
234 [] -- No equality spec
236 arg_tys (mkTyConApp tycon (mkTyVarTys tyvars))
238 [] -- No stupid theta
239 (mkDataConIds bogus_wrap_name wrk_name data_con)
242 modu = ASSERT( isExternalName dc_name )
244 wrk_occ = mkDataConWorkerOcc (nameOccName dc_name)
245 wrk_key = incrUnique (nameUnique dc_name)
246 wrk_name = mkWiredInName modu wrk_occ wrk_key
247 (AnId (dataConWorkId data_con)) UserSyntax
248 bogus_wrap_name = pprPanic "Wired-in data wrapper id" (ppr dc_name)
249 -- Wired-in types are too simple to need wrappers
253 %************************************************************************
255 \subsection[TysWiredIn-tuples]{The tuple types}
257 %************************************************************************
260 tupleTyCon :: Boxity -> Arity -> TyCon
261 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i) -- Build one specially
262 tupleTyCon Boxed i = fst (boxedTupleArr ! i)
263 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
265 tupleCon :: Boxity -> Arity -> DataCon
266 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i) -- Build one specially
267 tupleCon Boxed i = snd (boxedTupleArr ! i)
268 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
270 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
271 boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]]
272 unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]]
274 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
275 mk_tuple boxity arity = (tycon, tuple_con)
277 tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info
278 modu = mkTupleModule boxity arity
279 tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
280 (ATyCon tycon) BuiltInSyntax
281 tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
282 res_kind | isBoxed boxity = liftedTypeKind
283 | otherwise = ubxTupleKind
285 tyvars | isBoxed boxity = take arity alphaTyVars
286 | otherwise = take arity openAlphaTyVars
288 tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
289 tyvar_tys = mkTyVarTys tyvars
290 dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
291 (ADataCon tuple_con) BuiltInSyntax
292 tc_uniq = mkTupleTyConUnique boxity arity
293 dc_uniq = mkTupleDataConUnique boxity arity
294 gen_info = True -- Tuples all have generics..
295 -- hmm: that's a *lot* of code
298 unitTyCon = tupleTyCon Boxed 0
299 unitDataCon :: DataCon
300 unitDataCon = head (tyConDataCons unitTyCon)
302 unitDataConId = dataConWorkId unitDataCon
305 pairTyCon = tupleTyCon Boxed 2
307 unboxedSingletonTyCon :: TyCon
308 unboxedSingletonTyCon = tupleTyCon Unboxed 1
309 unboxedSingletonDataCon :: DataCon
310 unboxedSingletonDataCon = tupleCon Unboxed 1
312 unboxedPairTyCon :: TyCon
313 unboxedPairTyCon = tupleTyCon Unboxed 2
314 unboxedPairDataCon :: DataCon
315 unboxedPairDataCon = tupleCon Unboxed 2
319 %************************************************************************
321 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
323 %************************************************************************
327 charTy = mkTyConTy charTyCon
330 charTyCon = pcNonRecDataTyCon charTyConName [] [charDataCon]
331 charDataCon :: DataCon
332 charDataCon = pcDataCon charDataConName [] [charPrimTy] charTyCon
335 stringTy = mkListTy charTy -- convenience only
340 intTy = mkTyConTy intTyCon
343 intTyCon = pcNonRecDataTyCon intTyConName [] [intDataCon]
344 intDataCon :: DataCon
345 intDataCon = pcDataCon intDataConName [] [intPrimTy] intTyCon
350 wordTy = mkTyConTy wordTyCon
353 wordTyCon = pcNonRecDataTyCon wordTyConName [] [wordDataCon]
354 wordDataCon :: DataCon
355 wordDataCon = pcDataCon wordDataConName [] [wordPrimTy] wordTyCon
360 floatTy = mkTyConTy floatTyCon
363 floatTyCon = pcNonRecDataTyCon floatTyConName [] [floatDataCon]
364 floatDataCon :: DataCon
365 floatDataCon = pcDataCon floatDataConName [] [floatPrimTy] floatTyCon
370 doubleTy = mkTyConTy doubleTyCon
373 doubleTyCon = pcNonRecDataTyCon doubleTyConName [] [doubleDataCon]
375 doubleDataCon :: DataCon
376 doubleDataCon = pcDataCon doubleDataConName [] [doublePrimTy] doubleTyCon
380 %************************************************************************
382 \subsection[TysWiredIn-Bool]{The @Bool@ type}
384 %************************************************************************
386 An ordinary enumeration type, but deeply wired in. There are no
387 magical operations on @Bool@ (just the regular Prelude code).
389 {\em BEGIN IDLE SPECULATION BY SIMON}
391 This is not the only way to encode @Bool@. A more obvious coding makes
392 @Bool@ just a boxed up version of @Bool#@, like this:
395 data Bool = MkBool Bool#
398 Unfortunately, this doesn't correspond to what the Report says @Bool@
399 looks like! Furthermore, we get slightly less efficient code (I
400 think) with this coding. @gtInt@ would look like this:
403 gtInt :: Int -> Int -> Bool
404 gtInt x y = case x of I# x# ->
406 case (gtIntPrim x# y#) of
410 Notice that the result of the @gtIntPrim@ comparison has to be turned
411 into an integer (here called @b#@), and returned in a @MkBool@ box.
413 The @if@ expression would compile to this:
416 MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
419 I think this code is a little less efficient than the previous code,
420 but I'm not certain. At all events, corresponding with the Report is
421 important. The interesting thing is that the language is expressive
422 enough to describe more than one alternative; and that a type doesn't
423 necessarily need to be a straightforwardly boxed version of its
424 primitive counterpart.
426 {\em END IDLE SPECULATION BY SIMON}
430 boolTy = mkTyConTy boolTyCon
433 boolTyCon = pcTyCon True NonRecursive boolTyConName
434 [] [falseDataCon, trueDataCon]
436 falseDataCon, trueDataCon :: DataCon
437 falseDataCon = pcDataCon falseDataConName [] [] boolTyCon
438 trueDataCon = pcDataCon trueDataConName [] [] boolTyCon
440 falseDataConId, trueDataConId :: Id
441 falseDataConId = dataConWorkId falseDataCon
442 trueDataConId = dataConWorkId trueDataCon
445 %************************************************************************
447 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
449 %************************************************************************
451 Special syntax, deeply wired in, but otherwise an ordinary algebraic
454 data [] a = [] | a : (List a)
456 data (,) a b = (,,) a b
461 mkListTy :: Type -> Type
462 mkListTy ty = mkTyConApp listTyCon [ty]
465 listTyCon = pcRecDataTyCon listTyConName alpha_tyvar [nilDataCon, consDataCon]
467 nilDataCon :: DataCon
468 nilDataCon = pcDataCon nilDataConName alpha_tyvar [] listTyCon
470 consDataCon :: DataCon
471 consDataCon = pcDataConWithFixity True {- Declared infix -}
473 alpha_tyvar [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
474 -- Interesting: polymorphic recursion would help here.
475 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
476 -- gets the over-specific type (Type -> Type)
479 %************************************************************************
481 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
483 %************************************************************************
485 The tuple types are definitely magic, because they form an infinite
490 They have a special family of type constructors, of type @TyCon@
491 These contain the tycon arity, but don't require a Unique.
494 They have a special family of constructors, of type
495 @Id@. Again these contain their arity but don't need a Unique.
498 There should be a magic way of generating the info tables and
499 entry code for all tuples.
501 But at the moment we just compile a Haskell source
502 file\srcloc{lib/prelude/...} containing declarations like:
505 data Tuple2 a b = Tup2 a b
506 data Tuple3 a b c = Tup3 a b c
507 data Tuple4 a b c d = Tup4 a b c d
510 The print-names associated with the magic @Id@s for tuple constructors
511 ``just happen'' to be the same as those generated by these
515 The instance environment should have a magic way to know
516 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
517 so on. \ToDo{Not implemented yet.}
520 There should also be a way to generate the appropriate code for each
521 of these instances, but (like the info tables and entry code) it is
522 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
526 mkTupleTy :: Boxity -> [Type] -> Type
527 -- Special case for *boxed* 1-tuples, which are represented by the type itself
528 mkTupleTy boxity [ty] | Boxed <- boxity = ty
529 mkTupleTy boxity tys = mkTyConApp (tupleTyCon boxity (length tys)) tys
531 -- | Build the type of a small tuple that holds the specified type of thing
532 mkBoxedTupleTy :: [Type] -> Type
533 mkBoxedTupleTy tys = mkTupleTy Boxed tys
536 unitTy = mkTupleTy Boxed []
539 %************************************************************************
541 \subsection[TysWiredIn-PArr]{The @[::]@ type}
543 %************************************************************************
545 Special syntax for parallel arrays needs some wired in definitions.
548 -- | Construct a type representing the application of the parallel array constructor
549 mkPArrTy :: Type -> Type
550 mkPArrTy ty = mkTyConApp parrTyCon [ty]
552 -- | Represents the type constructor of parallel arrays
554 -- * This must match the definition in @PrelPArr@
556 -- NB: Although the constructor is given here, it will not be accessible in
557 -- user code as it is not in the environment of any compiled module except
561 parrTyCon = pcNonRecDataTyCon parrTyConName alpha_tyvar [parrDataCon]
563 parrDataCon :: DataCon
564 parrDataCon = pcDataCon
566 alpha_tyvar -- forall'ed type variables
567 [intPrimTy, -- 1st argument: Int#
568 mkTyConApp -- 2nd argument: Array# a
573 -- | Check whether a type constructor is the constructor for parallel arrays
574 isPArrTyCon :: TyCon -> Bool
575 isPArrTyCon tc = tyConName tc == parrTyConName
577 -- | Fake array constructors
579 -- * These constructors are never really used to represent array values;
580 -- however, they are very convenient during desugaring (and, in particular,
581 -- in the pattern matching compiler) to treat array pattern just like
582 -- yet another constructor pattern
584 parrFakeCon :: Arity -> DataCon
585 parrFakeCon i | i > mAX_TUPLE_SIZE = mkPArrFakeCon i -- build one specially
586 parrFakeCon i = parrFakeConArr!i
588 -- pre-defined set of constructors
590 parrFakeConArr :: Array Int DataCon
591 parrFakeConArr = array (0, mAX_TUPLE_SIZE) [(i, mkPArrFakeCon i)
592 | i <- [0..mAX_TUPLE_SIZE]]
594 -- build a fake parallel array constructor for the given arity
596 mkPArrFakeCon :: Int -> DataCon
597 mkPArrFakeCon arity = data_con
599 data_con = pcDataCon name [tyvar] tyvarTys parrTyCon
600 tyvar = head alphaTyVars
601 tyvarTys = replicate arity $ mkTyVarTy tyvar
602 nameStr = mkFastString ("MkPArr" ++ show arity)
603 name = mkWiredInName gHC_PARR (mkDataOccFS nameStr) unique
604 (ADataCon data_con) UserSyntax
605 unique = mkPArrDataConUnique arity
607 -- | Checks whether a data constructor is a fake constructor for parallel arrays
608 isPArrFakeCon :: DataCon -> Bool
609 isPArrFakeCon dcon = dcon == parrFakeCon (dataConSourceArity dcon)