[project @ 1998-02-03 17:13:54 by simonm]
[ghc-hetmet.git] / ghc / compiler / types / TyCon.lhs
index c975f35..0ce00b1 100644 (file)
@@ -1,18 +1,17 @@
-%
+
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[TyCon]{The @TyCon@ datatype}
 
 \begin{code}
-#include "HsVersions.h"
-
 module TyCon(
-       TyCon(..),      -- NB: some pals need to see representation
+       TyCon,
 
-       Arity(..), NewOrData(..),
+       Arity, NewOrData(..),
 
-       isFunTyCon, isPrimTyCon, isBoxedTyCon,
-       isDataTyCon, isSynTyCon, isNewTyCon,
+       isFunTyCon, isPrimTyCon, isBoxedTyCon, isProductTyCon,
+       isAlgTyCon, isDataTyCon, isSynTyCon, isNewTyCon, 
+       isEnumerationTyCon, isTupleTyCon, 
 
        mkDataTyCon,
        mkFunTyCon,
@@ -28,52 +27,57 @@ module TyCon(
        tyConDataCons,
        tyConFamilySize,
        tyConDerivings,
-       tyConArity, synTyConArity,
+       tyConTheta,
+       tyConPrimRep,
+       tyConArity,
+       tyConClass_maybe,
        getSynTyConDefn,
 
-        maybeTyConSingleCon,
-       isEnumerationTyCon,
-       derivedFor
+        maybeTyConSingleCon
 ) where
 
-CHK_Ubiq()     -- debugging consistency check
+#include "HsVersions.h"
 
-import TyLoop          ( Type(..), GenType,
-                         Class(..), GenClass,
-                         Id(..), GenId,
-                         mkTupleCon, dataConSig,
-                         specMaybeTysSuffix
-                       )
+import {-# SOURCE #-} Type  ( Type )
+import {-# SOURCE #-} Class ( Class )
+import {-# SOURCE #-} Id    ( Id, isNullaryDataCon )
+import {-# SOURCE #-} TysWiredIn ( tupleCon )
 
-import TyVar           ( GenTyVar, alphaTyVars, alphaTyVar, betaTyVar )
-import Usage           ( GenUsage, Usage(..) )
-import Kind            ( Kind, mkBoxedTypeKind, mkArrowKind, resultKind, argKind )
 
-import Maybes
-import Name            ( Name, RdrName(..), appendRdr, nameUnique,
-                         mkTupleTyConName, mkFunTyConName
+import BasicTypes      ( Arity, NewOrData(..), RecFlag(..) )
+import TyVar           ( GenTyVar, alphaTyVars, alphaTyVar, betaTyVar, TyVar )
+import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind, mkUnboxedTypeKind,
+                         mkArrowKind, resultKind, argKind
                        )
-import Unique          ( Unique, funTyConKey, mkTupleTyConUnique )
-import Pretty          ( Pretty(..), PrettyRep )
-import PprStyle                ( PprStyle )
-import SrcLoc          ( SrcLoc, mkBuiltinSrcLoc )
-import Util            ( panic, panic#, nOfThem, isIn, Ord3(..) )
+import Maybes
+import Name            ( Name, nameUnique, mkWiredInTyConName, NamedThing(getName) )
+import Unique          ( Unique, funTyConKey, Uniquable(..) )
+import PrimRep         ( PrimRep(..), isFollowableRep )
+import PrelMods                ( pREL_GHC )
+import Util            ( panic )
 \end{code}
 
 \begin{code}
-type Arity = Int
-
 data TyCon
   = FunTyCon           -- Kind = Type -> Type -> Type
 
-  | DataTyCon  Unique{-TyConKey-}
+  | DataTyCon  Unique
                Name
                Kind
                [TyVar]
-               [(Class,Type)]  -- Its context
-               [Id]            -- Its data constructors, with fully polymorphic types
+               [(Class,[Type])]        -- Its context
+               [Id{-DataCon-}] -- Its data constructors, with fully polymorphic types
+                               --      This list can be empty, when we import a data type abstractly,
+                               --      either (a) the interface is hand-written and doesn't give
+                               --                 the constructors, or
+                               --             (b) in a quest for fast compilation we don't import 
+                               --                 the constructors
                [Class]         -- Classes which have derived instances
+               (Maybe Class)   -- Nothing for ordinary types; Just c for the type constructor
+                               -- for dictionaries of class c.
                NewOrData
+               RecFlag         -- Tells whether the data type is part of 
+                               -- a mutually-recursive group or not
 
   | TupleTyCon Unique          -- cached
                Name            -- again, we could do without this, but
@@ -85,9 +89,11 @@ data TyCon
                        --      -> BoxedTypeKind
 
   | PrimTyCon          -- Primitive types; cannot be defined in Haskell
-       Unique          -- Always unboxed; hence never represented by a closure
+       Unique          -- Always unpointed; hence never represented by a closure
        Name            -- Often represented by a bit-pattern for the thing
        Kind            -- itself (eg Int#), but sometimes by a pointer to
+       Arity           -- the thing.
+       PrimRep
 
   | SpecTyCon          -- A specialised TyCon; eg (Arr# Int#), or (List Int#)
        TyCon
@@ -109,50 +115,67 @@ data TyCon
        Type            -- Right-hand side, mentioning these type vars.
                        -- Acts as a template for the expansion when
                        -- the tycon is applied to some types.
-
-data NewOrData
-  = NewType        -- "newtype Blah ..."
-  | DataType       -- "data Blah ..."
 \end{code}
 
 \begin{code}
-mkFunTyCon   = FunTyCon
+mkFunTyCon     = FunTyCon
+mkFunTyConName = mkWiredInTyConName funTyConKey pREL_GHC SLIT("->") FunTyCon
+
 mkSpecTyCon  = SpecTyCon
+mkTupleTyCon = TupleTyCon
+
+mkDataTyCon name = DataTyCon (nameUnique name) name
 
-mkTupleTyCon arity
-  = TupleTyCon u n arity 
+mkPrimTyCon name arity rep 
+  = PrimTyCon (nameUnique name) name (mk_kind arity) arity rep
   where
-    n = mkTupleTyConName arity
-    u = uniqueOf n
+    mk_kind 0 | isFollowableRep rep = mkBoxedTypeKind  -- Represented by a GC-ish ptr
+             | otherwise           = mkUnboxedTypeKind -- Represented by a non-ptr
+    mk_kind n = mkTypeKind `mkArrowKind` mk_kind (n-1)
 
-mkDataTyCon name
-  = DataTyCon (nameUnique name) name
-mkPrimTyCon name
-  = PrimTyCon (nameUnique name) name
-mkSynTyCon name
-  = SynTyCon (nameUnique name) name
+mkSynTyCon  name = SynTyCon  (nameUnique name) name
 
 isFunTyCon FunTyCon = True
 isFunTyCon _ = False
 
-isPrimTyCon (PrimTyCon _ _ _) = True
+isPrimTyCon (PrimTyCon _ _ _ _ _) = True
 isPrimTyCon _ = False
 
 -- At present there are no unboxed non-primitive types, so
 -- isBoxedTyCon is just the negation of isPrimTyCon.
 isBoxedTyCon = not . isPrimTyCon
 
+-- isAlgTyCon returns True for both @data@ and @newtype@
+isAlgTyCon (DataTyCon _ _ _ _ _ _ _ _ _ _) = True
+isAlgTyCon (TupleTyCon _ _ _)             = True
+isAlgTyCon other                          = False
+
 -- isDataTyCon returns False for @newtype@.
--- Not sure about this decision yet.
-isDataTyCon (DataTyCon _ _ _ _ _ _ _ DataType) = True
-isDataTyCon (TupleTyCon _ _ _)                = True
-isDataTyCon other                             = False
+isDataTyCon (DataTyCon _ _ _ _ _ _ _ _ DataType _) = True
+isDataTyCon (TupleTyCon _ _ _)                            = True
+isDataTyCon other                                 = False
+
+isNewTyCon (DataTyCon _ _ _ _ _ _ _ _ NewType _) = True 
+isNewTyCon other                                = False
 
-isNewTyCon (DataTyCon _ _ _ _ _ _ _ NewType) = True 
-isNewTyCon other                            = False
+-- A "product" tycon is non-recursive and has one constructor,
+-- whether DataType or NewType
+isProductTyCon (TupleTyCon _ _ _)                          = True
+isProductTyCon (DataTyCon _ _ _ _ _ [c] _ _ _ NonRecursive) = True
+isProductTyCon other                                       = False
 
 isSynTyCon (SynTyCon _ _ _ _ _ _) = True
 isSynTyCon _                     = False
+
+isEnumerationTyCon (TupleTyCon _ _ arity)
+  = arity == 0
+isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _ DataType _)
+  = not (null data_cons) && all isNullaryDataCon data_cons
+isEnumerationTyCon other = False
+
+isTupleTyCon (TupleTyCon _ _ arity) = arity >= 2    -- treat "0-tuple" specially
+isTupleTyCon (SpecTyCon tc tys)     = isTupleTyCon tc
+isTupleTyCon other                 = False
 \end{code}
 
 \begin{code}
@@ -161,10 +184,10 @@ kind1 = mkBoxedTypeKind `mkArrowKind` mkBoxedTypeKind
 kind2 = mkBoxedTypeKind `mkArrowKind` kind1
 
 tyConKind :: TyCon -> Kind
-tyConKind FunTyCon                      = kind2
-tyConKind (DataTyCon _ _ kind _ _ _ _ _) = kind
-tyConKind (PrimTyCon _ _ kind)          = kind
-tyConKind (SynTyCon _ _ k _ _ _)        = k
+tyConKind FunTyCon                          = kind2
+tyConKind (DataTyCon _ _ kind _ _ _ _ _ _ _) = kind
+tyConKind (PrimTyCon _ _ kind _ _)          = kind
+tyConKind (SynTyCon _ _ k _ _ _)            = k
 
 tyConKind (TupleTyCon _ _ n)
   = mkArrow n
@@ -185,55 +208,67 @@ tyConKind (SpecTyCon tc tys)
 
 \begin{code}
 tyConUnique :: TyCon -> Unique
-tyConUnique FunTyCon                      = funTyConKey
-tyConUnique (DataTyCon uniq _ _ _ _ _ _ _) = uniq
-tyConUnique (TupleTyCon uniq _ _)         = uniq
-tyConUnique (PrimTyCon uniq _ _)          = uniq
-tyConUnique (SynTyCon uniq _ _ _ _ _)      = uniq
-tyConUnique (SpecTyCon _ _ )              = panic "tyConUnique:SpecTyCon"
-
-tyConArity :: TyCon -> Arity
-tyConArity FunTyCon                     = 2
-tyConArity (DataTyCon _ _ _ tvs _ _ _ _) = length tvs
-tyConArity (TupleTyCon _ _ arity)       = arity
-tyConArity (PrimTyCon _ _ _)            = 0    -- ??
-tyConArity (SpecTyCon _ _)              = 0
-tyConArity (SynTyCon _ _ _ arity _ _)    = arity
-
-synTyConArity :: TyCon -> Maybe Arity -- Nothing <=> not a syn tycon
-synTyConArity (SynTyCon _ _ _ arity _ _) = Just arity
-synTyConArity _                                 = Nothing
+tyConUnique FunTyCon                          = funTyConKey
+tyConUnique (DataTyCon uniq _ _ _ _ _ _ _ _ _) = uniq
+tyConUnique (TupleTyCon uniq _ _)             = uniq
+tyConUnique (PrimTyCon uniq _ _ _ _)          = uniq
+tyConUnique (SynTyCon uniq _ _ _ _ _)          = uniq
+tyConUnique (SpecTyCon _ _ )                  = panic "tyConUnique:SpecTyCon"
+
+tyConArity :: TyCon -> Arity 
+tyConArity FunTyCon                            = 2
+tyConArity (DataTyCon _ _ _ tyvars _ _ _ _ _ _) = length tyvars
+tyConArity (TupleTyCon _ _ arity)              = arity
+tyConArity (PrimTyCon _ _ _ arity _)           = arity 
+tyConArity (SynTyCon _ _ _ arity _ _)          = arity
+tyConArity (SpecTyCon _ _ )                    = panic "tyConArity:SpecTyCon"
 \end{code}
 
 \begin{code}
 tyConTyVars :: TyCon -> [TyVar]
-tyConTyVars FunTyCon                     = [alphaTyVar,betaTyVar]
-tyConTyVars (DataTyCon _ _ _ tvs _ _ _ _) = tvs
-tyConTyVars (TupleTyCon _ _ arity)       = take arity alphaTyVars
-tyConTyVars (SynTyCon _ _ _ _ tvs _)      = tvs
-tyConTyVars (PrimTyCon _ _ _)            = panic "tyConTyVars:PrimTyCon"
+tyConTyVars FunTyCon                         = [alphaTyVar,betaTyVar]
+tyConTyVars (DataTyCon _ _ _ tvs _ _ _ _ _ _) = tvs
+tyConTyVars (TupleTyCon _ _ arity)           = take arity alphaTyVars
+tyConTyVars (SynTyCon _ _ _ _ tvs _)          = tvs
+#ifdef DEBUG
+tyConTyVars (PrimTyCon _ _ _ _ _)        = panic "tyConTyVars:PrimTyCon"
 tyConTyVars (SpecTyCon _ _ )             = panic "tyConTyVars:SpecTyCon"
+#endif
 \end{code}
 
 \begin{code}
 tyConDataCons :: TyCon -> [Id]
 tyConFamilySize  :: TyCon -> Int
 
-tyConDataCons (DataTyCon _ _ _ _ _ data_cons _ _) = data_cons
-tyConDataCons (TupleTyCon _ _ a)                 = [mkTupleCon a]
-tyConDataCons other                              = []
+tyConDataCons (DataTyCon _ _ _ _ _ data_cons _ _ _ _) = data_cons
+tyConDataCons (TupleTyCon _ _ a)                     = [tupleCon a]
+tyConDataCons other                                  = []
        -- You may think this last equation should fail,
        -- but it's quite convenient to return no constructors for
        -- a synonym; see for example the call in TcTyClsDecls.
 
-tyConFamilySize (DataTyCon _ _ _ _ _ data_cons _ _) = length data_cons
-tyConFamilySize (TupleTyCon _ _ _)                 = 1
+tyConFamilySize (DataTyCon _ _ _ _ _ data_cons _ _ _ _) = length data_cons
+tyConFamilySize (TupleTyCon _ _ _)                     = 1
+#ifdef DEBUG
+--tyConFamilySize other = pprPanic "tyConFamilySize:" (pprTyCon other)
+#endif
+
+tyConPrimRep :: TyCon -> PrimRep
+tyConPrimRep (PrimTyCon _ __  _ rep) = rep
+tyConPrimRep _                      = PtrRep
 \end{code}
 
 \begin{code}
 tyConDerivings :: TyCon -> [Class]
-tyConDerivings (DataTyCon _ _ _ _ _ _ derivs _) = derivs
-tyConDerivings other                           = []
+tyConDerivings (DataTyCon _ _ _ _ _ _ derivs _ _ _) = derivs
+tyConDerivings other                               = []
+\end{code}
+
+\begin{code}
+tyConTheta :: TyCon -> [(Class, [Type])]
+tyConTheta (DataTyCon _ _ _ _ theta _ _ _ _ _) = theta
+tyConTheta (TupleTyCon _ _ _)                 = []
+-- should ask about anything else
 \end{code}
 
 \begin{code}
@@ -244,20 +279,18 @@ getSynTyConDefn (SynTyCon _ _ _ _ tyvars ty) = (tyvars,ty)
 \begin{code}
 maybeTyConSingleCon :: TyCon -> Maybe Id
 
-maybeTyConSingleCon (TupleTyCon _ _ arity)        = Just (mkTupleCon arity)
-maybeTyConSingleCon (DataTyCon _ _ _ _ _ [c] _ _) = Just c
-maybeTyConSingleCon (DataTyCon _ _ _ _ _ _   _ _) = Nothing
-maybeTyConSingleCon (PrimTyCon _ _ _)            = Nothing
-maybeTyConSingleCon (SpecTyCon tc tys)            = panic "maybeTyConSingleCon:SpecTyCon"
+maybeTyConSingleCon (TupleTyCon _ _ arity)            = Just (tupleCon arity)
+maybeTyConSingleCon (DataTyCon _ _ _ _ _ [c] _ _ _ _) = Just c
+maybeTyConSingleCon (DataTyCon _ _ _ _ _ _   _ _ _ _) = Nothing
+maybeTyConSingleCon (PrimTyCon _ _ _ _ _)             = Nothing
+maybeTyConSingleCon (SpecTyCon tc tys)                = panic "maybeTyConSingleCon:SpecTyCon"
                                                  -- requires DataCons of TyCon
+\end{code}
 
-isEnumerationTyCon (TupleTyCon _ _ arity)
-  = arity == 0
-isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _)
-  = not (null data_cons) && all is_nullary data_cons
-  where
-    is_nullary con = case (dataConSig con) of { (_,_, arg_tys, _) ->
-                    null arg_tys }
+\begin{code}
+tyConClass_maybe :: TyCon -> Maybe Class
+tyConClass_maybe (DataTyCon _ _ _ _ _ _ _ maybe_cls _ _) = maybe_cls
+tyConClass_maybe other_tycon                            = Nothing
 \end{code}
 
 @derivedFor@ reports if we have an {\em obviously}-derived instance
@@ -267,12 +300,6 @@ function doesn't deal with that.
 
 ToDo: what about derivings for specialised tycons !!!
 
-\begin{code}
-derivedFor :: Class -> TyCon -> Bool
-derivedFor clas (DataTyCon _ _ _ _ _ _ derivs _) = isIn "derivedFor" clas derivs
-derivedFor clas something_weird                         = False
-\end{code}
-
 %************************************************************************
 %*                                                                     *
 \subsection[TyCon-instances]{Instance declarations for @TyCon@}
@@ -285,62 +312,32 @@ The strictness analyser needs @Ord@. It is a lexicographic order with
 the property @(a<=b) || (b<=a)@.
 
 \begin{code}
-instance Ord3 TyCon where
-  cmp FunTyCon                   FunTyCon                    = EQ_
-  cmp (DataTyCon a _ _ _ _ _ _ _) (DataTyCon b _ _ _ _ _ _ _) = a `cmp` b
-  cmp (SynTyCon a _ _ _ _ _)      (SynTyCon b _ _ _ _ _)      = a `cmp` b
-  cmp (TupleTyCon _ _ a)          (TupleTyCon _ _ b)         = a `cmp` b
-  cmp (PrimTyCon a _ _)                  (PrimTyCon b _ _)           = a `cmp` b
-  cmp (SpecTyCon tc1 mtys1)      (SpecTyCon tc2 mtys2)
-    = panic# "cmp on SpecTyCons" -- case (tc1 `cmp` tc2) of { EQ_ -> mtys1 `cmp` mtys2; xxx -> xxx }
-
-    -- now we *know* the tags are different, so...
-  cmp other_1 other_2
-    | tag1 _LT_ tag2 = LT_
-    | otherwise      = GT_
-    where
-      tag1 = tag_TyCon other_1
-      tag2 = tag_TyCon other_2
-
-      tag_TyCon FunTyCon                   = ILIT(1)
-      tag_TyCon (DataTyCon _ _ _ _ _ _ _ _) = ILIT(2)
-      tag_TyCon (TupleTyCon _ _ _)         = ILIT(3)
-      tag_TyCon (PrimTyCon  _ _ _)         = ILIT(4)
-      tag_TyCon (SpecTyCon  _ _)           = ILIT(5)
-      tag_TyCon (SynTyCon _ _ _ _ _ _)     = ILIT(6)
-
 instance Eq TyCon where
-    a == b = case (a `cmp` b) of { EQ_ -> True;   _ -> False }
-    a /= b = case (a `cmp` b) of { EQ_ -> False;  _ -> True  }
+    a == b = case (a `compare` b) of { EQ -> True;   _ -> False }
+    a /= b = case (a `compare` b) of { EQ -> False;  _ -> True  }
 
 instance Ord TyCon where
-    a <= b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
-    _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
+    a <= b = case (a `compare` b) of { LT -> True;  EQ -> True;  GT -> False }
+    a <         b = case (a `compare` b) of { LT -> True;  EQ -> False; GT -> False }
+    a >= b = case (a `compare` b) of { LT -> False; EQ -> True;  GT -> True  }
+    a >         b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True  }
+    compare a b = uniqueOf a `compare` uniqueOf b
 
 instance Uniquable TyCon where
-    uniqueOf (DataTyCon  u _ _ _ _ _ _ _) = u
-    uniqueOf (TupleTyCon u _ _)                  = u
-    uniqueOf (PrimTyCon  u _ _)                  = u
-    uniqueOf (SynTyCon   u _ _ _ _ _)    = u
-    uniqueOf tc@(SpecTyCon _ _)                  = panic "uniqueOf:SpecTyCon"
-    uniqueOf tc                                  = uniqueOf (getName tc)
+    uniqueOf tc = tyConUnique tc
 \end{code}
 
 \begin{code}
 instance NamedThing TyCon where
-    getName (DataTyCon _ n _ _ _ _ _ _) = n
-    getName (PrimTyCon _ n _)          = n
-    getName (SpecTyCon tc _)           = getName tc
-    getName (SynTyCon _ n _ _ _ _)     = n
-    getName FunTyCon                   = mkFunTyConName
-    getName (TupleTyCon _ n _)         = n
-    getName tc                         = panic "TyCon.getName"
+    getName (DataTyCon _ n _ _ _ _ _ _ _ _) = n
+    getName (PrimTyCon _ n _ _ _)          = n
+    getName (SpecTyCon tc _)               = getName tc
+    getName (SynTyCon _ n _ _ _ _)         = n
+    getName FunTyCon                       = mkFunTyConName
+    getName (TupleTyCon _ n _)             = n
 
 {- LATER:
-    getName (SpecTyCon tc tys) = let (m,n) = moduleNamePair tc in
+    getName (SpecTyCon tc tys) = let (OrigName m n) = origName "????" tc in
                                     (m, n _APPEND_ specMaybeTysSuffix tys)
     getName    other_tc           = moduleNamePair (expectJust "tycon1" (getName other_tc))
     getName other                           = Nothing