isTupleTyCon, isUnboxedTupleTyCon, isBoxedTupleTyCon, tupleTyConBoxity,
isRecursiveTyCon, newTyConRep,
+ mkForeignTyCon, isForeignTyCon,
+
mkAlgTyCon, --mkAlgTyCon,
mkClassTyCon,
mkFunTyCon,
mkPrimTyCon,
+ mkLiftedPrimTyCon,
mkTupleTyCon,
mkSynTyCon,
mkKindCon,
import PrelNames ( Unique, Uniquable(..), anyBoxConKey )
import PrimRep ( PrimRep(..), isFollowableRep )
import Outputable
+import FastString
\end{code}
%************************************************************************
algTyConClass :: Maybe Class -- Just cl if this tycon came from a class declaration
}
- | PrimTyCon { -- Primitive types; cannot be defined in Haskell
- -- NB: All of these guys are *unlifted*, but not all are *unboxed*
+ | PrimTyCon { -- Primitive types; cannot be defined in Haskell
+ -- Now includes foreign-imported types
tyConUnique :: Unique,
tyConName :: Name,
tyConKind :: Kind,
tyConArity :: Arity,
tyConArgVrcs :: ArgVrcs,
- primTyConRep :: PrimRep
+ primTyConRep :: PrimRep, -- Many primitive tycons are unboxed, but some are
+ -- boxed (represented by pointers). The PrimRep tells.
+
+ isUnLifted :: Bool, -- Most primitive tycons are unlifted,
+ -- but foreign-imported ones may not be
+ tyConExtName :: Maybe FastString
}
| TupleTyCon {
data AlgTyConFlavour
= DataTyCon -- Data type
+
| EnumTyCon -- Special sort of enumeration type
+
| NewTyCon Type -- Newtype, with its *ultimate* representation type
-- By 'ultimate' I mean that the rep type is not itself
-- a newtype or type synonym.
- -- The rep type has explicit for-alls for the tyvars of
- -- the TyCon. Thus:
+ -- The rep type has free type variables the tyConTyVars
+ -- Thus:
-- newtype T a = MkT [(a,Int)]
- -- The rep type is forall a. [(a,Int)]
+ -- The rep type is [(a,Int)]
--
-- The rep type isn't entirely simple:
-- for a recursive newtype we pick () as the rep type
genInfo = gen_info
}
-mkClassTyCon name kind tyvars argvrcs con clas flavour
+mkClassTyCon name kind tyvars argvrcs con clas flavour rec
= AlgTyCon {
tyConName = name,
tyConUnique = nameUnique name,
noOfDataCons = 1,
algTyConClass = Just clas,
algTyConFlavour = flavour,
- algTyConRec = NonRecursive,
+ algTyConRec = rec,
genInfo = Nothing
}
genInfo = gen_info
}
-mkPrimTyCon name kind arity arg_vrcs rep
+-- Foreign-imported (.NET) type constructors are represented
+-- as primitive, but *lifted*, TyCons for now. They are lifted
+-- because the Haskell type T representing the (foreign) .NET
+-- type T is actually implemented (in ILX) as a thunk<T>
+-- They have PtrRep
+mkForeignTyCon name ext_name kind arity arg_vrcs
= PrimTyCon {
- tyConName = name,
- tyConUnique = nameUnique name,
- tyConKind = kind,
- tyConArity = arity,
+ tyConName = name,
+ tyConUnique = nameUnique name,
+ tyConKind = kind,
+ tyConArity = arity,
tyConArgVrcs = arg_vrcs,
- primTyConRep = rep
+ primTyConRep = PtrRep,
+ isUnLifted = False,
+ tyConExtName = ext_name
+ }
+
+
+-- most Prim tycons are lifted
+mkPrimTyCon name kind arity arg_vrcs rep
+ = mkPrimTyCon' name kind arity arg_vrcs rep True
+
+-- but RealWorld is lifted
+mkLiftedPrimTyCon name kind arity arg_vrcs rep
+ = mkPrimTyCon' name kind arity arg_vrcs rep False
+
+mkPrimTyCon' name kind arity arg_vrcs rep is_unlifted
+ = PrimTyCon {
+ tyConName = name,
+ tyConUnique = nameUnique name,
+ tyConKind = kind,
+ tyConArity = arity,
+ tyConArgVrcs = arg_vrcs,
+ primTyConRep = rep,
+ isUnLifted = is_unlifted,
+ tyConExtName = Nothing
}
mkSynTyCon name kind arity tyvars rhs argvrcs
isPrimTyCon (PrimTyCon {}) = True
isPrimTyCon _ = False
-isUnLiftedTyCon (PrimTyCon {}) = True
-isUnLiftedTyCon (TupleTyCon { tyConBoxed = boxity}) = not (isBoxed boxity)
-isUnLiftedTyCon _ = False
+isUnLiftedTyCon (PrimTyCon {isUnLifted = is_unlifted}) = is_unlifted
+isUnLiftedTyCon (TupleTyCon {tyConBoxed = boxity}) = not (isBoxed boxity)
+isUnLiftedTyCon _ = False
-- isBoxedTyCon should not be applied to SynTyCon, nor KindCon
isBoxedTyCon (AlgTyCon {}) = True
isAlgTyCon (TupleTyCon {}) = True
isAlgTyCon other = False
--- isDataTyCon returns False for @newtype@ and for unboxed tuples
-isDataTyCon (AlgTyCon {algTyConFlavour = new_or_data}) = case new_or_data of
- NewTyCon _ -> False
- other -> True
+-- isDataTyCon returns True for data types that are represented by
+-- heap-allocated constructors.
+-- These are srcutinised by Core-level @case@ expressions, and they
+-- get info tables allocated for them.
+-- True for all @data@ types
+-- False for newtypes
+-- unboxed tuples
+isDataTyCon (AlgTyCon {algTyConFlavour = new_or_data, algTyConRec = is_rec})
+ = case new_or_data of
+ NewTyCon _ -> False
+ other -> True
+
isDataTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
isDataTyCon other = False
isNewTyCon (AlgTyCon {algTyConFlavour = NewTyCon _}) = True
isNewTyCon other = False
-newTyConRep (AlgTyCon {algTyConFlavour = NewTyCon rep}) = Just rep
-newTyConRep other = Nothing
+newTyConRep :: TyCon -> ([TyVar], Type)
+newTyConRep (AlgTyCon {tyConTyVars = tvs, algTyConFlavour = NewTyCon rep}) = (tvs, rep)
-- A "product" tycon
-- has *one* constructor,
isRecursiveTyCon (AlgTyCon {algTyConRec = Recursive}) = True
isRecursiveTyCon other = False
+
+-- isForeignTyCon identifies foreign-imported type constructors
+-- For the moment, they are primitive but lifted, but that may change
+isForeignTyCon (PrimTyCon {isUnLifted = is_unlifted}) = not is_unlifted
+isForeignTyCon other = False
\end{code}
\begin{code}
tyConDataCons :: TyCon -> [DataCon]
-tyConDataCons tycon = ASSERT2( not (null cons), ppr tycon )
- ASSERT2( length cons == tyConFamilySize tycon, ppr tycon )
+tyConDataCons tycon = ASSERT2( length cons == tyConFamilySize tycon, ppr tycon )
cons
where
cons = tyConDataConsIfAvailable tycon
\begin{code}
tyConPrimRep :: TyCon -> PrimRep
tyConPrimRep (PrimTyCon {primTyConRep = rep}) = rep
-tyConPrimRep _ = PtrRep
+tyConPrimRep tc = ASSERT( not (isUnboxedTupleTyCon tc) )
+ PtrRep
+ -- We should not be asking what the representation of an
+ -- unboxed tuple is, because it isn't a first class value.
\end{code}
\begin{code}
tyConTheta :: TyCon -> [PredType]
tyConTheta (AlgTyCon {algTyConTheta = theta}) = theta
--- should ask about anything else
+tyConTheta (TupleTyCon {}) = []
+-- shouldn't ask about anything else
\end{code}
@tyConArgVrcs_maybe@ gives a list of (occPos,occNeg) flags, one for