Commit 51f116ef authored by simonpj's avatar simonpj
Browse files

[project @ 2004-02-24 16:44:26 by simonpj]

---------------------------------------
      Allow constructors to be specified in hi-boot files
	  ---------------------------------------
parent 53fe9413
......@@ -327,10 +327,12 @@ ifacedecl :: { HsDecl RdrName }
{ SigD (Sig $1 $3) }
| 'type' syn_hdr '=' ctype
{ let (tc,tvs) = $2 in TyClD (TySynonym tc tvs $4) }
| 'data' tycl_hdr
{ TyClD (mkTyData DataType (unLoc $2) [] Nothing) }
| 'newtype' tycl_hdr
| 'data' tycl_hdr constrs -- No deriving in hi-boot
{ TyClD (mkTyData DataType (unLoc $2) (reverse (unLoc $3)) Nothing) }
| 'newtype' tycl_hdr -- Constructor is optional
{ TyClD (mkTyData NewType (unLoc $2) [] Nothing) }
| 'newtype' tycl_hdr '=' newconstr
{ TyClD (mkTyData NewType (unLoc $2) [$4] Nothing) }
| 'class' tycl_hdr fds
{ TyClD (mkClassDecl (unLoc $2) (unLoc $3) [] emptyBag) }
......
......@@ -51,7 +51,7 @@ module RdrHsSyn (
import HsSyn -- Lots of it
import IfaceType
import HscTypes ( ModIface(..), emptyModIface, mkIfaceVerCache )
import IfaceSyn ( IfaceDecl(..), IfaceIdInfo(..) )
import IfaceSyn ( IfaceDecl(..), IfaceIdInfo(..), IfaceConDecl(..) )
import RdrName ( RdrName, isRdrTyVar, mkUnqual, rdrNameOcc,
isRdrTyVar, isRdrDataCon, isUnqual, getRdrName, isQual,
setRdrNameSpace, rdrNameModule )
......@@ -64,7 +64,7 @@ import ForeignCall ( CCallConv, Safety, CCallTarget(..), CExportSpec(..),
DNCallSpec(..), DNKind(..))
import OccName ( OccName, srcDataName, varName, isDataOcc, isTcOcc,
occNameUserString, isValOcc )
import BasicTypes ( initialVersion )
import BasicTypes ( initialVersion, StrictnessMark(..) )
import TyCon ( DataConDetails(..) )
import Module ( ModuleName )
import SrcLoc
......@@ -246,7 +246,8 @@ hsIfaceDecl (TyClD decl@(TyData {}))
ifName = rdrNameOcc (tcdName decl),
ifTyVars = hsIfaceTvs (tcdTyVars decl),
ifCtxt = hsIfaceCtxt (unLoc (tcdCtxt decl)),
ifCons = Unknown, ifRec = NonRecursive,
ifCons = hsIfaceCons (tcdCons decl),
ifRec = NonRecursive,
ifVrcs = [], ifGeneric = False }
-- I'm not sure that [] is right for ifVrcs, but
-- since we don't use them I'm not going to fiddle
......@@ -261,6 +262,35 @@ hsIfaceDecl (TyClD decl@(ClassDecl {}))
hsIfaceDecl decl = pprPanic "hsIfaceDecl" (ppr decl)
hsIfaceCons :: [LConDecl RdrName] -> DataConDetails IfaceConDecl
hsIfaceCons cons
| null cons -- data T a, meaning "constructors unspecified", not "no constructors"
= Unknown
| otherwise -- data T a = C1 | C2
= DataCons (map (hsIfaceCon . unLoc) cons)
hsIfaceCon :: ConDecl RdrName -> IfaceConDecl
hsIfaceCon (ConDecl lname ex_tvs ex_ctxt details)
= IfaceConDecl (get_occ lname)
(hsIfaceTvs ex_tvs)
(hsIfaceCtxt (unLoc ex_ctxt))
(map (hsIfaceLType . getBangType . unLoc) args)
(map (hsStrictMark . getBangStrictness . unLoc) args)
flds
where
(args, flds) = case details of
PrefixCon args -> (args, [])
InfixCon a1 a2 -> ([a1,a2], [])
RecCon fs -> (map snd fs, map (get_occ . fst) fs)
get_occ lname = rdrNameOcc (unLoc lname)
hsStrictMark :: HsBang -> StrictnessMark
-- Warning: in source files the {-# UNPACK #-} pragma (HsUnbox) is a request
-- but in an hi-boot file it's interpreted as the Truth!
hsStrictMark HsNoBang = NotMarkedStrict
hsStrictMark HsStrict = MarkedStrict
hsStrictMark HsUnbox = MarkedUnboxed
hsIfaceName rdr_name -- Qualify unqualifed occurrences
-- with the module name
| isUnqual rdr_name = LocalTop (rdrNameOcc rdr_name)
......
......@@ -948,6 +948,32 @@ newtype GHC.IOBase.IO a
<literal>instances</literal> or derive them automatically.
</para>
</listitem>
<listitem> <para>For <literal>data</literal> or <literal>newtype</literal> declaration, you may omit all
the constructors, thus:
<ProgramListing>
module A where
data TA
</ProgramListing>
(You must write all the type parameters, but omit the
'=' and everything that follows it.) In a <emphasis>source</emphasis> program
this would declare TA to have no constructors (a GHC extension: see <xref linkend="nullary-types">),
but in an hi-boot file it means "I don't know or care what the construtors are".
This is the most common form of data type declaration, because it's easy to get right.</para>
<para>
You <emphasis>can</emphasis> also write out the constructors but, if you do so, you must write
it out precisely as in its real definition.
It is especially delicate if you use a strictness annotation "!",
with or without an <literal>{-# UNPACK #-}</literal> pragma. In a source file
GHC may or may not choose to unbox the argument, but in an hi-boot file it's
assumed that you express the <emphasis>outcome</emphasis> of this decision.
(So in the cases where GHC decided not to unpack, you must not use the pragma.)
Tread with care.</para>
</listitem>
<listitem> <para>For <literal>class</literal> declaration, you may not specify any class
operations. We could lift this restriction if it became tiresome.</para>
</listitem>
</itemizedlist>
<para>Notice that we only put the declaration for the newtype
......@@ -955,18 +981,6 @@ newtype GHC.IOBase.IO a
not the signature for <Function>f</Function>, since
<Function>f</Function> isn't used by <literal>B</literal>.</para>
<para>If you want an <literal>hi-boot</literal> file to export a
data type, but you don't want to give its constructors (because
the constructors aren't used by the SOURCE-importing module),
you can write simply:</para>
<ProgramListing>
module A where
data TA
</ProgramListing>
<para>(You must write all the type parameters, but leave out the
'=' and everything that follows it.)</para>
</sect2>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment