[project @ 2002-10-09 15:36:47 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcExpr.lhs
index f6f822b..c3dde2f 100644 (file)
@@ -9,11 +9,10 @@ module TcExpr ( tcExpr, tcExpr_id, tcMonoExpr ) where
 #include "HsVersions.h"
 
 #ifdef GHCI    /* Only if bootstrapped */
-import {-# SOURCE #-}  TcSplice( tcSpliceExpr )
-import TcEnv           ( bracketOK, tcMetaTy )
+import {-# SOURCE #-}  TcSplice( tcSpliceExpr, tcBracket )
+import TcEnv           ( bracketOK )
 import TcSimplify      ( tcSimplifyBracket )
-import PrelNames       ( exprTyConName )
-import HsSyn           ( HsBracket(..) )
+import DsMeta          ( liftName )
 #endif
 
 import HsSyn           ( HsExpr(..), HsLit(..), ArithSeqInfo(..), 
@@ -53,9 +52,7 @@ import TcType         ( TcType, TcSigmaType, TcRhoType, TyVarDetails(VanillaTv),
                        )
 import FieldLabel      ( FieldLabel, fieldLabelName, fieldLabelType, fieldLabelTyCon )
 import Id              ( Id, idType, recordSelectorFieldLabel, isRecordSelector, isDataConWrapId_maybe )
-import DataCon         ( dataConFieldLabels, dataConSig, 
-                         dataConStrictMarks
-                       )
+import DataCon         ( DataCon, dataConFieldLabels, dataConSig, dataConStrictMarks )
 import Name            ( Name, isExternalName )
 import TyCon           ( TyCon, tyConTyVars, tyConTheta, isAlgTyCon, tyConDataCons )
 import Subst           ( mkTopTyVarSubst, substTheta, substTy )
@@ -65,7 +62,7 @@ import PrelNames      ( cCallableClassName, cReturnableClassName,
                          enumFromName, enumFromThenName, 
                          enumFromToName, enumFromThenToName,
                          enumFromToPName, enumFromThenToPName,
-                         ioTyConName, liftName
+                         ioTyConName
                        )
 import ListSetOps      ( minusList )
 import CmdLineOpts
@@ -405,16 +402,8 @@ tcMonoExpr expr@(RecordCon con_name rbinds) res_ty
        -- Typecheck the record bindings
     tcRecordBinds tycon ty_args rbinds         `thenM` \ rbinds' ->
     
-    let
-      (missing_s_fields, missing_fields) = missingFields rbinds data_con
-    in
-    checkM (null missing_s_fields)
-       (mappM_ (addErrTc . missingStrictFieldCon con_name) missing_s_fields)
-                                       `thenM_`
-    doptM Opt_WarnMissingFields                `thenM` \ warn ->
-    checkM (not (warn && notNull missing_fields))
-       (mappM_ ((warnTc True) . missingFieldCon con_name) missing_fields)
-                                       `thenM_`
+       -- Check for missing fields
+    checkMissingFields data_con rbinds         `thenM_` 
 
     returnM (RecordConOut data_con con_expr rbinds')
 
@@ -634,7 +623,7 @@ tcMonoExpr (PArrSeqIn _) _
 
 tcMonoExpr (HsSplice n expr) res_ty = tcSpliceExpr n expr res_ty
   
-tcMonoExpr (HsBracket (ExpBr expr)) res_ty
+tcMonoExpr (HsBracket brack) res_ty
   = getStage                                   `thenM` \ level ->
     case bracketOK level of {
        Nothing         -> failWithTc (illegalBracket level) ;
@@ -645,19 +634,17 @@ tcMonoExpr (HsBracket (ExpBr expr)) res_ty
        -- it again when we actually use it.
     newMutVar []                       `thenM` \ pending_splices ->
     getLIEVar                          `thenM` \ lie_var ->
-    newTyVarTy openTypeKind            `thenM` \ any_ty ->
 
     setStage (Brack next_level pending_splices lie_var) (
-       getLIE (tcMonoExpr expr any_ty)
-    )                                          `thenM` \ (expr', lie) ->
-    tcSimplifyBracket lie                      `thenM_`  
+       getLIE (tcBracket brack)
+    )                                  `thenM` \ (meta_ty, lie) ->
+    tcSimplifyBracket lie              `thenM_`  
 
-    tcMetaTy exprTyConName                     `thenM` \ meta_exp_ty ->
-    unifyTauTy res_ty meta_exp_ty              `thenM_`
+    unifyTauTy res_ty meta_ty          `thenM_`
 
        -- Return the original expression, not the type-decorated one
     readMutVar pending_splices         `thenM` \ pendings ->
-    returnM (HsBracketOut (ExpBr expr) pendings)
+    returnM (HsBracketOut brack pendings)
     }
 #endif GHCI
 \end{code}
@@ -822,6 +809,7 @@ tcId name   -- Look up the Id and instantiate its type
   = tcLookupIdLvl name                 `thenM` \ (id, bind_lvl) ->
 
        -- Check for cross-stage lifting
+#ifdef GHCI
     getStage                           `thenM` \ use_stage -> 
     case use_stage of
       Brack use_lvl ps_var lie_var
@@ -860,7 +848,8 @@ tcId name   -- Look up the Id and instantiate its type
        in
        checkTc (wellStaged bind_lvl use_lvl)
                (badStageErr id bind_lvl use_lvl)       `thenM_`
-
+#endif
+       -- This is the bit that handles the no-Template-Haskell case
        case isDataConWrapId_maybe id of
                Nothing       -> loop (HsVar id) (idType id)
                Just data_con -> inst_data_con id data_con
@@ -981,18 +970,31 @@ badFields rbinds data_con
   where
     field_names = map fieldLabelName (dataConFieldLabels data_con)
 
-missingFields rbinds data_con
-  | null field_labels = ([], [])       -- Not declared as a record;
-                                       -- But C{} is still valid
-  | otherwise  
-  = (missing_strict_fields, other_missing_fields)
+checkMissingFields :: DataCon -> RenamedRecordBinds -> TcM ()
+checkMissingFields data_con rbinds
+  | null field_labels  -- Not declared as a record;
+                       -- But C{} is still valid if no strict fields
+  = if any isMarkedStrict field_strs then
+       -- Illegal if any arg is strict
+       addErrTc (missingStrictFields data_con [])
+    else
+       returnM ()
+                       
+  | otherwise          -- A record
+  = checkM (null missing_s_fields)
+          (addErrTc (missingStrictFields data_con missing_s_fields))   `thenM_`
+
+    doptM Opt_WarnMissingFields                `thenM` \ warn ->
+    checkM (not (warn && notNull missing_ns_fields))
+          (warnTc True (missingFields data_con missing_ns_fields))
+
   where
-    missing_strict_fields
+    missing_s_fields
        = [ fl | (fl, str) <- field_info,
                 isMarkedStrict str,
                 not (fieldLabelName fl `elem` field_names_used)
          ]
-    other_missing_fields
+    missing_ns_fields
        = [ fl | (fl, str) <- field_info,
                 not (isMarkedStrict str),
                 not (fieldLabelName fl `elem` field_names_used)
@@ -1003,7 +1005,9 @@ missingFields rbinds data_con
 
     field_info = zipEqual "missingFields"
                          field_labels
-                         (dropList ex_theta (dataConStrictMarks data_con))
+                         field_strs
+
+    field_strs = dropList ex_theta (dataConStrictMarks data_con)
        -- The 'drop' is because dataConStrictMarks
        -- includes the existential dictionaries
     (_, _, _, ex_theta, _, _) = dataConSig data_con
@@ -1122,15 +1126,22 @@ recordConCtxt expr = ptext SLIT("In the record construction:") <+> ppr expr
 notSelector field
   = hsep [quotes (ppr field), ptext SLIT("is not a record selector")]
 
-missingStrictFieldCon :: Name -> FieldLabel -> SDoc
-missingStrictFieldCon con field
-  = hsep [ptext SLIT("Constructor") <+> quotes (ppr con),
-         ptext SLIT("does not have the required strict field"), quotes (ppr field)]
-
-missingFieldCon :: Name -> FieldLabel -> SDoc
-missingFieldCon con field
-  = hsep [ptext SLIT("Field") <+> quotes (ppr field),
-         ptext SLIT("is not initialised")]
+missingStrictFields :: DataCon -> [FieldLabel] -> SDoc
+missingStrictFields con fields
+  = header <> rest
+  where
+    rest | null fields = empty -- Happens for non-record constructors 
+                               -- with strict fields
+        | otherwise   = colon <+> pprWithCommas ppr fields
+
+    header = ptext SLIT("Constructor") <+> quotes (ppr con) <+> 
+            ptext SLIT("does not have the required strict field(s)") 
+         
+
+missingFields :: DataCon -> [FieldLabel] -> SDoc
+missingFields con fields
+  = ptext SLIT("Fields of") <+> quotes (ppr con) <+> ptext SLIT("not initialised:") 
+       <+> pprWithCommas ppr fields
 
 polySpliceErr :: Id -> SDoc
 polySpliceErr id