[project @ 2000-02-10 18:39:51 by lewie]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcTyDecls.lhs
index 181f830..1a3c2c3 100644 (file)
@@ -18,40 +18,42 @@ import HsSyn                ( MonoBinds(..),
                        )
 import RnHsSyn         ( RenamedTyClDecl, RenamedConDecl )
 import TcHsSyn         ( TcMonoBinds )
-import BasicTypes      ( RecFlag(..), NewOrData(..), StrictnessMark(..) )
+import BasicTypes      ( RecFlag(..), NewOrData(..) )
 
 import TcMonoType      ( tcExtendTopTyVarScope, tcExtendTyVarScope, 
                          tcHsTypeKind, tcHsType, tcHsTopType, tcHsTopBoxedType,
-                         tcContext
+                         tcContext, tcHsTopTypeKind
                        )
-import TcType          ( zonkTcTyVarToTyVar, zonkTcThetaType )
+import TcType          ( zonkTcTyVarToTyVar, zonkTcClassConstraints )
 import TcEnv           ( tcLookupTy, TcTyThing(..) )
 import TcMonad
 import TcUnify         ( unifyKind )
 
 import Class           ( Class )
 import DataCon         ( DataCon, dataConSig, mkDataCon, isNullaryDataCon,
-                         dataConFieldLabels, dataConId
+                         dataConFieldLabels, dataConId,
+                         markedStrict, notMarkedStrict, markedUnboxed
                        )
-import MkId            ( mkDataConId, mkRecordSelId )
+import MkId            ( mkDataConId, mkRecordSelId, mkNewTySelId )
 import Id              ( getIdUnfolding )
-import CoreUnfold      ( getUnfoldingTemplate )
+import CoreUnfold      ( unfoldingTemplate )
 import FieldLabel
 import Var             ( Id, TyVar )
-import Name            ( isLocallyDefined, OccName, NamedThing(..) )
+import Name            ( Name, isLocallyDefined, OccName, NamedThing(..), nameUnique )
 import Outputable
-import TyCon           ( TyCon, mkSynTyCon, mkAlgTyCon, isAlgTyCon, 
-                         isSynTyCon, tyConDataCons
+import TyCon           ( TyCon, ArgVrcs, mkSynTyCon, mkAlgTyCon, isAlgTyCon, 
+                         isSynTyCon, tyConDataCons, isNewTyCon
                        )
 import Type            ( getTyVar, tyVarsOfTypes,
                          mkTyConApp, mkTyVarTys, mkForAllTys, mkFunTy,
                          mkTyVarTy,
                          mkArrowKind, mkArrowKinds, boxedTypeKind,
-                         isUnboxedType, Type, ThetaType
+                         isUnboxedType, Type, ThetaType, classesOfPreds
                        )
 import Var             ( tyVarKind )
 import VarSet          ( intersectVarSet, isEmptyVarSet )
 import Util            ( equivClasses )
+import FiniteMap        ( FiniteMap, lookupWithDefaultFM )
 \end{code}
 
 %************************************************************************
@@ -86,11 +88,12 @@ kcConDecl (ConDecl _ ex_tvs ex_ctxt details loc)
   where
     kc_con (VanillaCon btys)    = mapTc kc_bty btys            `thenTc_` returnTc ()
     kc_con (InfixCon bty1 bty2) = mapTc kc_bty [bty1,bty2]     `thenTc_` returnTc ()
-    kc_con (NewCon ty)         = tcHsType ty                   `thenTc_` returnTc ()
+    kc_con (NewCon ty _)        = tcHsType ty                  `thenTc_` returnTc ()
     kc_con (RecCon flds)        = mapTc kc_field flds          `thenTc_` returnTc ()
 
     kc_bty (Banged ty)   = tcHsType ty
     kc_bty (Unbanged ty) = tcHsType ty
+    kc_bty (Unpacked ty) = tcHsType ty
 
     kc_field (_, bty)    = kc_bty bty
 \end{code}
@@ -103,27 +106,30 @@ kcConDecl (ConDecl _ ex_tvs ex_ctxt details loc)
 %************************************************************************
 
 \begin{code}
-tcTyDecl :: RecFlag -> RenamedTyClDecl -> TcM s TyCon
+tcTyDecl :: RecFlag -> FiniteMap Name ArgVrcs -> RenamedTyClDecl -> TcM s TyCon
 
-tcTyDecl is_rec (TySynonym tycon_name tyvar_names rhs src_loc)
+tcTyDecl is_rec rec_vrcs (TySynonym tycon_name tyvar_names rhs src_loc)
   = tcLookupTy tycon_name                              `thenNF_Tc` \ (tycon_kind, Just arity, _) ->
     tcExtendTopTyVarScope tycon_kind tyvar_names       $ \ tyvars _ ->
-    tcHsTopType rhs                                    `thenTc` \ rhs_ty ->
+    tcHsTopTypeKind rhs                                        `thenTc` \ (_, rhs_ty) ->
     let
        -- Construct the tycon
-       tycon = mkSynTyCon tycon_name tycon_kind arity tyvars rhs_ty
+        argvrcs = lookupWithDefaultFM rec_vrcs (pprPanic "tcTyDecl: argvrcs:" $ ppr tycon_name)
+                                      tycon_name
+       tycon = mkSynTyCon tycon_name tycon_kind arity tyvars rhs_ty argvrcs
     in
     returnTc tycon
 
 
-tcTyDecl is_rec (TyData data_or_new context tycon_name tyvar_names con_decls derivings pragmas src_loc)
+tcTyDecl is_rec rec_vrcs (TyData data_or_new context tycon_name tyvar_names con_decls derivings pragmas src_loc)
   =    -- Lookup the pieces
     tcLookupTy tycon_name                              `thenNF_Tc` \ (tycon_kind, _, ATyCon rec_tycon) ->
     tcExtendTopTyVarScope tycon_kind tyvar_names       $ \ tyvars _ ->
 
        -- Typecheck the pieces
     tcContext context                                  `thenTc` \ ctxt ->
-    mapTc (tcConDecl rec_tycon tyvars ctxt) con_decls  `thenTc` \ data_cons ->
+    let ctxt' = classesOfPreds ctxt in
+    mapTc (tcConDecl rec_tycon tyvars ctxt') con_decls `thenTc` \ data_cons ->
     tc_derivs derivings                                        `thenTc` \ derived_classes ->
 
     let
@@ -133,7 +139,10 @@ tcTyDecl is_rec (TyData data_or_new context tycon_name tyvar_names con_decls der
                                DataType | all isNullaryDataCon data_cons -> EnumType
                                         | otherwise                      -> DataType
 
-       tycon = mkAlgTyCon tycon_name tycon_kind tyvars ctxt
+        argvrcs = lookupWithDefaultFM rec_vrcs (pprPanic "tcTyDecl: argvrcs:" $ ppr tycon_name)
+                                      tycon_name
+
+       tycon = mkAlgTyCon tycon_name tycon_kind tyvars ctxt' argvrcs
                           data_cons
                           derived_classes
                           Nothing              -- Not a dictionary
@@ -156,19 +165,20 @@ tcTyDecl is_rec (TyData data_or_new context tycon_name tyvar_names con_decls der
 %************************************************************************
 
 \begin{code}
-tcConDecl :: TyCon -> [TyVar] -> ThetaType -> RenamedConDecl -> TcM s DataCon
+tcConDecl :: TyCon -> [TyVar] -> [(Class,[Type])] -> RenamedConDecl -> TcM s DataCon
 
 tcConDecl tycon tyvars ctxt (ConDecl name ex_tvs ex_ctxt details src_loc)
   = tcAddSrcLoc src_loc                        $
     tcExtendTyVarScope ex_tvs          $ \ ex_tyvars -> 
     tcContext ex_ctxt                  `thenTc` \ ex_theta ->
-    tc_con_decl_help tycon tyvars ctxt name ex_tyvars ex_theta details
+    let ex_ctxt' = classesOfPreds ex_theta in
+    tc_con_decl_help tycon tyvars ctxt name ex_tyvars ex_ctxt' details
 
 tc_con_decl_help tycon tyvars ctxt name ex_tyvars ex_theta details
   = case details of
        VanillaCon btys    -> tc_datacon btys
        InfixCon bty1 bty2 -> tc_datacon [bty1,bty2]
-       NewCon ty          -> tc_newcon ty
+       NewCon ty mb_f     -> tc_newcon ty mb_f
        RecCon fields      -> tc_rec_con fields
   where
     tc_datacon btys
@@ -179,11 +189,17 @@ tc_con_decl_help tycon tyvars ctxt name ex_tyvars ex_theta details
        mapTc tcHsTopType tys `thenTc` \ arg_tys ->
        mk_data_con arg_stricts arg_tys []
 
-    tc_newcon ty 
+    tc_newcon ty mb_f
       = tcHsTopBoxedType ty    `thenTc` \ arg_ty ->
            -- can't allow an unboxed type here, because we're effectively
            -- going to remove the constructor while coercing it to a boxed type.
-       mk_data_con [NotMarkedStrict] [arg_ty] []
+       let
+         field_label =
+           case mb_f of
+             Nothing -> []
+             Just f  -> [mkFieldLabel (getName f) arg_ty (head allFieldLabelTags)]
+        in           
+       mk_data_con [notMarkedStrict] [arg_ty] field_label
 
     tc_rec_con fields
       = checkTc (null ex_tyvars) (exRecConErr name)        `thenTc_`
@@ -209,7 +225,7 @@ tc_con_decl_help tycon tyvars ctxt name ex_tyvars ex_theta details
                -- immutable type variables.  (The top-level tyvars are
                -- already fixed, by the preceding kind-inference pass.)
        mapNF_Tc zonkTcTyVarToTyVar ex_tyvars   `thenNF_Tc` \ ex_tyvars' ->
-       zonkTcThetaType ex_theta                `thenNF_Tc` \ ex_theta' ->
+       zonkTcClassConstraints  ex_theta        `thenNF_Tc` \ ex_theta' ->
        let
           data_con = mkDataCon name arg_stricts fields
                           tyvars (thinContext arg_tys ctxt)
@@ -229,11 +245,13 @@ thinContext arg_tys ctxt
       in_arg_tys (clas,tys) = not $ isEmptyVarSet $ 
                              tyVarsOfTypes tys `intersectVarSet` arg_tyvars
   
-get_strictness (Banged   _) = MarkedStrict
-get_strictness (Unbanged _) = NotMarkedStrict
+get_strictness (Banged   _) = markedStrict
+get_strictness (Unbanged _) = notMarkedStrict
+get_strictness (Unpacked _) = markedUnboxed
 
 get_pty (Banged ty)   = ty
 get_pty (Unbanged ty) = ty
+get_pty (Unpacked ty) = ty
 \end{code}
 
 
@@ -254,16 +272,18 @@ mkDataBinds (tycon : tycons)
                       returnTc (ids1++ids2, b1 `AndMonoBinds` b2)
 
 mkDataBinds_one tycon
-  = ASSERT( isAlgTyCon tycon )
-    mapTc (mkRecordSelector tycon) groups      `thenTc` \ sel_ids ->
+  = mapTc (mkRecordSelector tycon) groups      `thenTc` \ sel_ids ->
     let
        data_ids = map dataConId data_cons ++ sel_ids
 
        -- For the locally-defined things
        -- we need to turn the unfoldings inside the Ids into bindings,
-       binds = [ CoreMonoBind data_id (getUnfoldingTemplate (getIdUnfolding data_id))
+       binds | isLocallyDefined tycon
+             = [ CoreMonoBind data_id (unfoldingTemplate (getIdUnfolding data_id))
                | data_id <- data_ids, isLocallyDefined data_id
                ]
+             | otherwise
+             = []
     in 
     returnTc (data_ids, andMonoBindList binds)
   where
@@ -303,7 +323,9 @@ mkRecordSelector tycon fields@((first_con, first_field_label) : other_fields)
                   field_ty
       
     selector_id :: Id
-    selector_id = mkRecordSelId first_field_label selector_ty
+    selector_id 
+      | isNewTyCon tycon    = mkNewTySelId  first_field_label selector_ty
+      | otherwise          = mkRecordSelId first_field_label selector_ty
 \end{code}