Straightened out implicit coercions for indexed types
[ghc-hetmet.git] / compiler / iface / IfaceSyn.lhs
index 0801f10..5f9c1d8 100644 (file)
@@ -38,7 +38,6 @@ import IfaceType
 import NewDemand       ( StrictSig, pprIfaceStrictSig )
 import TcType          ( deNoteType )
 import Class           ( FunDep, DefMeth, pprFundeps )
-import TyCon           ( ArgVrcs )
 import OccName         ( OccName, parenSymOcc, occNameFS,
                          OccSet, unionOccSets, unitOccSet )
 import UniqFM           ( UniqFM, emptyUFM, addToUFM, lookupUFM )
@@ -71,31 +70,42 @@ data IfaceDecl
              ifType   :: IfaceType, 
              ifIdInfo :: IfaceIdInfo }
 
-  | IfaceData { ifName       :: OccName,               -- Type constructor
+  | IfaceData { ifName       :: OccName,       -- Type constructor
                ifTyVars     :: [IfaceTvBndr],  -- Type variables
                ifCtxt       :: IfaceContext,   -- The "stupid theta"
                ifCons       :: IfaceConDecls,  -- Includes new/data info
                ifRec        :: RecFlag,        -- Recursive or not?
-               ifVrcs       :: ArgVrcs,
-               ifGadtSyntax :: Bool,           -- True <=> declared using GADT syntax
-               ifGeneric    :: Bool            -- True <=> generic converter functions available
-    }                                          -- We need this for imported data decls, since the
-                                               -- imported modules may have been compiled with
-                                               -- different flags to the current compilation unit
-
-  | IfaceSyn  {        ifName   :: OccName,            -- Type constructor
-               ifTyVars :: [IfaceTvBndr],      -- Type variables
-               ifVrcs   :: ArgVrcs,
-               ifSynRhs :: IfaceType           -- synonym expansion
+               ifGadtSyntax :: Bool,           -- True <=> declared using
+                                               -- GADT syntax 
+               ifGeneric    :: Bool,           -- True <=> generic converter
+                                               --          functions available
+                                               -- We need this for imported
+                                               -- data decls, since the
+                                               -- imported modules may have
+                                               -- been compiled with
+                                               -- different flags to the
+                                               -- current compilation unit 
+                ifFamInst    :: Maybe           -- Just _ <=> instance of fam
+                                 (IfaceTyCon,  --   Family tycon
+                                  [IfaceType], --   Instance types
+                                  Int    )     --   Unique index for naming
+    }
+
+  | IfaceSyn  {        ifName    :: OccName,           -- Type constructor
+               ifTyVars  :: [IfaceTvBndr],     -- Type variables
+               ifOpenSyn :: Bool,              -- Is an open family?
+               ifSynRhs  :: IfaceType          -- Type for an ordinary
+                                               -- synonym and kind for an
+                                               -- open family
     }
 
   | IfaceClass { ifCtxt    :: IfaceContext,    -- Context...
                 ifName    :: OccName,          -- Name of the class
                 ifTyVars  :: [IfaceTvBndr],    -- Type variables
                 ifFDs     :: [FunDep FastString], -- Functional dependencies
+                ifATs     :: [IfaceDecl],      -- Associated type families
                 ifSigs    :: [IfaceClassOp],   -- Method signatures
-                ifRec     :: RecFlag,          -- Is newtype/datatype associated with the class recursive?
-                ifVrcs    :: ArgVrcs           -- ... and what are its argument variances ...
+                ifRec     :: RecFlag           -- Is newtype/datatype associated with the class recursive?
     }
 
   | IfaceForeign { ifName :: OccName,          -- Needs expanding when we move beyond .NET
@@ -108,11 +118,15 @@ data IfaceClassOp = IfaceClassOp OccName DefMeth IfaceType
 
 data IfaceConDecls
   = IfAbstractTyCon            -- No info
+  | IfOpenDataTyCon            -- Open data family
+  | IfOpenNewTyCon             -- Open newtype family
   | IfDataTyCon [IfaceConDecl] -- data type decls
   | IfNewTyCon  IfaceConDecl   -- newtype decls
 
 visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl]
 visibleIfConDecls IfAbstractTyCon  = []
+visibleIfConDecls IfOpenDataTyCon  = []
+visibleIfConDecls IfOpenNewTyCon   = []
 visibleIfConDecls (IfDataTyCon cs) = cs
 visibleIfConDecls (IfNewTyCon c)   = [c]
 
@@ -126,8 +140,9 @@ data IfaceConDecl
        ifConCtxt    :: IfaceContext,           -- Non-stupid context
        ifConArgTys  :: [IfaceType],            -- Arg types
        ifConFields  :: [OccName],              -- ...ditto... (field labels)
-       ifConStricts :: [StrictnessMark] }      -- Empty (meaning all lazy), or 1-1 corresp with arg types
-                       
+       ifConStricts :: [StrictnessMark]}       -- Empty (meaning all lazy),
+                                               -- or 1-1 corresp with arg tys
+
 data IfaceInst 
   = IfaceInst { ifInstCls  :: IfaceExtName,            -- See comments with
                ifInstTys  :: [Maybe IfaceTyCon],       -- the defn of Instance
@@ -199,7 +214,7 @@ data IfaceNote = IfaceSCC CostCentre
                | IfaceCoreNote String
 
 type IfaceAlt = (IfaceConAlt, [FastString], IfaceExpr)
-       -- Note: OccName, not IfaceBndr (and same with the case binder)
+       -- Note: FastString, not IfaceBndr (and same with the case binder)
        -- We reconstruct the kind/type of the thing from the context
        -- thus saving bulk in interface files
 
@@ -233,43 +248,59 @@ pprIfaceDecl (IfaceId {ifName = var, ifType = ty, ifIdInfo = info})
 pprIfaceDecl (IfaceForeign {ifName = tycon})
   = hsep [ptext SLIT("foreign import type dotnet"), ppr tycon]
 
-pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, ifSynRhs = mono_ty, ifVrcs = vrcs})
+pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, 
+                       ifOpenSyn = False, ifSynRhs = mono_ty})
   = hang (ptext SLIT("type") <+> pprIfaceDeclHead [] tycon tyvars)
-       4 (vcat [equals <+> ppr mono_ty,
-               pprVrcs vrcs])
+       4 (equals <+> ppr mono_ty)
+
+pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, 
+                       ifOpenSyn = True, ifSynRhs = mono_ty})
+  = hang (ptext SLIT("type family") <+> pprIfaceDeclHead [] tycon tyvars)
+       4 (dcolon <+> ppr mono_ty)
 
 pprIfaceDecl (IfaceData {ifName = tycon, ifGeneric = gen, ifCtxt = context,
                         ifTyVars = tyvars, ifCons = condecls, 
-                        ifRec = isrec, ifVrcs = vrcs})
+                        ifRec = isrec, ifFamInst = mbFamInst})
   = hang (pp_nd <+> pprIfaceDeclHead context tycon tyvars)
-       4 (vcat [pprVrcs vrcs, pprRec isrec, pprGen gen, pp_condecls tycon condecls])
+       4 (vcat [pprRec isrec, pprGen gen, pp_condecls tycon condecls,
+               pprFamily mbFamInst])
   where
     pp_nd = case condecls of
                IfAbstractTyCon -> ptext SLIT("data")
+               IfOpenDataTyCon -> ptext SLIT("data family")
                IfDataTyCon _   -> ptext SLIT("data")
                IfNewTyCon _    -> ptext SLIT("newtype")
+               IfOpenNewTyCon  -> ptext SLIT("newtype family")
 
 pprIfaceDecl (IfaceClass {ifCtxt = context, ifName = clas, ifTyVars = tyvars, 
-                         ifFDs = fds, ifSigs = sigs, ifVrcs = vrcs, ifRec = isrec})
+                         ifFDs = fds, ifATs = ats, ifSigs = sigs, 
+                         ifRec = isrec})
   = hang (ptext SLIT("class") <+> pprIfaceDeclHead context clas tyvars <+> pprFundeps fds)
-       4 (vcat [pprVrcs vrcs, 
-               pprRec isrec,
-               sep (map ppr sigs)])
+       4 (vcat [pprRec isrec,
+               sep (map ppr ats),
+               sep (map ppr sigs)])
 
-pprVrcs vrcs = ptext SLIT("Variances") <+> ppr vrcs
 pprRec isrec = ptext SLIT("RecFlag") <+> ppr isrec
 pprGen True  = ptext SLIT("Generics: yes")
 pprGen False = ptext SLIT("Generics: no")
 
+pprFamily Nothing                  = ptext SLIT("FamilyInstance: none")
+pprFamily (Just (fam, tys, index)) = ptext SLIT("FamilyInstance:") <+> 
+                                    ppr fam <+> hsep (map ppr tys) <+>
+                                    brackets (ppr index)
+
 instance Outputable IfaceClassOp where
    ppr (IfaceClassOp n dm ty) = ppr n <+> ppr dm <+> dcolon <+> ppr ty
 
 pprIfaceDeclHead :: IfaceContext -> OccName -> [IfaceTvBndr] -> SDoc
-pprIfaceDeclHead context thing tyvars 
-  = hsep [pprIfaceContext context, parenSymOcc thing (ppr thing), pprIfaceTvBndrs tyvars]
+pprIfaceDeclHead context thing tyvars
+  = hsep [pprIfaceContext context, parenSymOcc thing (ppr thing), 
+         pprIfaceTvBndrs tyvars]
 
 pp_condecls tc IfAbstractTyCon  = ptext SLIT("{- abstract -}")
+pp_condecls tc IfOpenNewTyCon   = empty
 pp_condecls tc (IfNewTyCon c)   = equals <+> pprIfaceConDecl tc c
+pp_condecls tc IfOpenDataTyCon  = empty
 pp_condecls tc (IfDataTyCon cs) = equals <+> sep (punctuate (ptext SLIT(" |"))
                                                             (map (pprIfaceConDecl tc) cs))
 
@@ -288,7 +319,8 @@ pprIfaceConDecl tc
     main_payload = ppr name <+> dcolon <+> 
                   pprIfaceForAllPart (univ_tvs ++ ex_tvs) (eq_ctxt ++ ctxt) (ppr con_tau)
 
-    eq_ctxt = [(IfaceEqPred (IfaceTyVar tv) ty) | (tv,ty) <- eq_spec] 
+    eq_ctxt = [(IfaceEqPred (IfaceTyVar (occNameFS tv)) ty) 
+             | (tv,ty) <- eq_spec] 
     con_tau = foldr1 IfaceFunTy (arg_tys ++ [tc_app])
     tc_app  = IfaceTyConApp (IfaceTc (LocalTop tc)) 
                            [IfaceTyVar tv | (tv,_) <- univ_tvs]
@@ -513,9 +545,9 @@ eqIfDecl d1@(IfaceForeign {}) d2@(IfaceForeign {})
 eqIfDecl d1@(IfaceData {}) d2@(IfaceData {})
   = bool (ifName d1    == ifName d2 && 
          ifRec d1     == ifRec   d2 && 
-         ifVrcs d1    == ifVrcs   d2 && 
          ifGadtSyntax d1 == ifGadtSyntax   d2 && 
          ifGeneric d1 == ifGeneric d2) &&&
+    ifFamInst d1 `eqIfTc_fam` ifFamInst d2 &&&
     eqWith (ifTyVars d1) (ifTyVars d2) (\ env -> 
            eq_ifContext env (ifCtxt d1) (ifCtxt d2) &&& 
            eq_hsCD env (ifCons d1) (ifCons d2) 
@@ -523,6 +555,11 @@ eqIfDecl d1@(IfaceData {}) d2@(IfaceData {})
        -- The type variables of the data type do not scope
        -- over the constructors (any more), but they do scope
        -- over the stupid context in the IfaceConDecls
+  where
+    Nothing                  `eqIfTc_fam` Nothing                  = Equal
+    (Just (fam1, tys1, co1)) `eqIfTc_fam` (Just (fam2, tys2, co2)) = 
+      fam1 `eqIfTc` fam2 &&& eqListBy eqIfType tys1 tys2 &&& bool (co1 == co2)
+    _                       `eqIfTc_fam` _                        = NotEqual
 
 eqIfDecl d1@(IfaceSyn {}) d2@(IfaceSyn {})
   = bool (ifName d1 == ifName d2) &&&
@@ -532,11 +569,11 @@ eqIfDecl d1@(IfaceSyn {}) d2@(IfaceSyn {})
 
 eqIfDecl d1@(IfaceClass {}) d2@(IfaceClass {})
   = bool (ifName d1 == ifName d2 && 
-         ifRec d1  == ifRec  d2 && 
-         ifVrcs d1 == ifVrcs d2) &&&
+         ifRec d1  == ifRec  d2) &&&
     eqWith (ifTyVars d1) (ifTyVars d2) (\ env -> 
          eq_ifContext env (ifCtxt d1) (ifCtxt d2)  &&&
          eqListBy (eq_hsFD env)    (ifFDs d1)  (ifFDs d2) &&&
+         eqListBy eqIfDecl         (ifATs d1)  (ifATs d2) &&&
          eqListBy (eq_cls_sig env) (ifSigs d1) (ifSigs d2)
        )
 
@@ -564,6 +601,8 @@ eq_hsCD env (IfDataTyCon c1) (IfDataTyCon c2)
 
 eq_hsCD env (IfNewTyCon c1)  (IfNewTyCon c2)  = eq_ConDecl env c1 c2
 eq_hsCD env IfAbstractTyCon  IfAbstractTyCon  = Equal
+eq_hsCD env IfOpenDataTyCon  IfOpenDataTyCon  = Equal
+eq_hsCD env IfOpenNewTyCon   IfOpenNewTyCon   = Equal
 eq_hsCD env d1              d2               = NotEqual
 
 eq_ConDecl env c1 c2