[project @ 1997-07-25 22:43:29 by sof]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcIfaceSig.lhs
index a34a061..3cdf851 100644 (file)
@@ -13,7 +13,8 @@ IMP_Ubiq()
 import TcMonad
 import TcMonoType      ( tcHsType, tcHsTypeKind )
 import TcEnv           ( tcLookupGlobalValue, tcExtendTyVarEnv, tcExtendGlobalValEnv,
-                         tcLookupTyConByKey, tcLookupGlobalValueMaybe, tcLookupLocalValue
+                         tcLookupTyConByKey, tcLookupGlobalValueMaybe, tcLookupLocalValue,
+                         tcExplicitLookupGlobal
                        )
 import TcKind          ( TcKind, kindToTcKind )
 
@@ -21,7 +22,7 @@ import HsSyn          ( IfaceSig(..), HsDecl(..), TyDecl, ClassDecl, InstDecl, DefaultDe
                          Fake, InPat, HsType )
 import RnHsSyn         ( RenamedHsDecl(..) )
 import HsCore
-import HsDecls         ( HsIdInfo(..) )
+import HsDecls         ( HsIdInfo(..), HsStrictnessInfo(..) )
 import Literal         ( Literal(..) )
 import CoreSyn
 import CoreUtils       ( coreExprType )
@@ -34,9 +35,9 @@ import PrimOp         ( PrimOp(..) )
 import Id              ( GenId, mkImported, mkUserId, addInlinePragma,
                          isPrimitiveId_maybe, dataConArgTys, SYN_IE(Id) )
 import Type            ( mkSynTy, getAppDataTyConExpandingDicts )
-import TyVar           ( mkTyVar )
+import TyVar           ( mkSysTyVar )
 import Name            ( Name )
-import Unique          ( rationalTyConKey )
+import Unique          ( rationalTyConKey, uniqueOf )
 import TysWiredIn      ( integerTy )
 import PragmaInfo      ( PragmaInfo(..) )
 import ErrUtils                ( pprBagOfErrors )
@@ -56,95 +57,91 @@ As always, we do not have to worry about user-pragmas in interface
 signatures.
 
 \begin{code}
-tcInterfaceSigs :: [RenamedHsDecl] -> TcM s [Id]
-                  -- Ignore non-sig-decls in these decls
-
-tcInterfaceSigs (SigD (IfaceSig name ty id_infos src_loc) : rest)
-  = tcAddSrcLoc src_loc $
-    tcAddErrCtxt (ifaceSigCtxt name) $
-    tcHsType ty                                        `thenTc` \ sigma_ty ->
-    tcIdInfo name sigma_ty noIdInfo id_infos   `thenTc` \ id_info' ->
-    let
-       imp_id = mkImported name sigma_ty id_info'
-       sig_id | any inline_please id_infos = addInlinePragma imp_id
-              | otherwise                  = imp_id
+tcInterfaceSigs :: TcEnv s             -- Envt to use when checking unfoldings
+               -> [RenamedHsDecl]      -- Ignore non-sig-decls in these decls
+               -> TcM s [Id]
+               
+
+tcInterfaceSigs unf_env (SigD (IfaceSig name ty id_infos src_loc) : rest)
+  = tcAddSrcLoc src_loc (
+    tcAddErrCtxt (ifaceSigCtxt name) (
+       tcHsType ty                                             `thenTc` \ sigma_ty ->
+       tcIdInfo unf_env name sigma_ty noIdInfo id_infos        `thenTc` \ id_info' ->
+       let
+           imp_id = mkImported name sigma_ty id_info'
+           sig_id | any inline_please id_infos = addInlinePragma imp_id
+                  | otherwise                  = imp_id
 
-       inline_please (HsUnfold inline _) = inline
-       inline_please other               = False
-    in
-    tcInterfaceSigs rest               `thenTc` \ sig_ids ->
+           inline_please (HsUnfold inline _) = inline
+           inline_please other           = False
+       in
+       returnTc sig_id
+    ))                                         `thenTc` \ sig_id ->
+    tcInterfaceSigs unf_env rest               `thenTc` \ sig_ids ->
     returnTc (sig_id : sig_ids)
 
-tcInterfaceSigs (other_decl : rest) = tcInterfaceSigs rest
+tcInterfaceSigs unf_env (other_decl : rest) = tcInterfaceSigs unf_env rest
 
-tcInterfaceSigs [] = returnTc []
+tcInterfaceSigs unf_env [] = returnTc []
 \end{code}
 
 \begin{code}
-tcIdInfo name ty info [] = returnTc info
-
-tcIdInfo name ty info (HsArity arity : rest)
-  = tcIdInfo name ty (info `addArityInfo` arity) rest
-
-tcIdInfo name ty info (HsUpdate upd : rest)
-  = tcIdInfo name ty (info `addUpdateInfo` upd) rest
-
-tcIdInfo name ty info (HsFBType fb : rest)
-  = tcIdInfo name ty (info `addFBTypeInfo` fb) rest
-
-tcIdInfo name ty info (HsArgUsage au : rest)
-  = tcIdInfo name ty (info `addArgUsageInfo` au) rest
-
-tcIdInfo name ty info (HsDeforest df : rest)
-  = tcIdInfo name ty (info `addDeforestInfo` df) rest
-
-tcIdInfo name ty info (HsUnfold inline expr : rest)
-  = tcUnfolding name expr      `thenNF_Tc` \ unfold_info ->
-    tcIdInfo name ty (info `addUnfoldInfo` unfold_info) rest
-
-tcIdInfo name ty info (HsStrictness strict : rest)
-  = tcStrictness ty info strict        `thenTc` \ info' ->
-    tcIdInfo name ty info' rest
+tcIdInfo unf_env name ty info info_ins
+  = go noIdInfo info_ins
+  where
+    go info_so_far []             = returnTc info_so_far
+    go info (HsArity arity : rest) = go (info `addArityInfo` arity) rest
+    go info (HsUpdate upd : rest)  = go (info `addUpdateInfo` upd)  rest
+    go info (HsFBType fb : rest)   = go (info `addFBTypeInfo` fb)   rest
+    go info (HsArgUsage au : rest) = go (info `addArgUsageInfo` au) rest
+    go info (HsDeforest df : rest) = go (info `addDeforestInfo` df) rest
+
+    go info (HsUnfold inline expr : rest) = tcUnfolding unf_env name expr      `thenNF_Tc` \ unfold_info ->
+                                           go (info `addUnfoldInfo` unfold_info) rest
+
+    go info (HsStrictness strict : rest)  = tcStrictness unf_env ty info strict        `thenTc` \ info' ->
+                                           go info' rest
 \end{code}
 
 \begin{code}
-tcStrictness ty info (StrictnessInfo demands maybe_worker)
-  = tcWorker maybe_worker                      `thenNF_Tc` \ maybe_worker_id ->
+tcStrictness unf_env ty info (HsStrictnessInfo demands maybe_worker)
+  = tcWorker unf_env maybe_worker              `thenNF_Tc` \ maybe_worker_id ->
     uniqSMToTcM (mkWrapper ty demands)         `thenNF_Tc` \ wrap_fn ->
     let
        -- Watch out! We can't pull on maybe_worker_id too eagerly!
        info' = case maybe_worker_id of
-                       Just (worker_id,_) -> info `addUnfoldInfo` mkUnfolding NoPragmaInfo (wrap_fn worker_id)
-                       Nothing            -> info
+                       Just worker_id -> info `addUnfoldInfo` mkUnfolding NoPragmaInfo (wrap_fn worker_id)
+                       Nothing        -> info
+       has_worker = maybeToBool maybe_worker_id
     in
-    returnTc (info' `addStrictnessInfo` StrictnessInfo demands maybe_worker_id)
+    returnTc (info' `addStrictnessInfo` StrictnessInfo demands has_worker)
 
 -- Boring to write these out, but the result type differs from the arg type...
-tcStrictness ty info BottomGuaranteed
+tcStrictness unf_env ty info HsBottom
   = returnTc (info `addStrictnessInfo` BottomGuaranteed)
-tcStrictness ty info NoStrictnessInfo
-  = returnTc info
 \end{code}
 
 \begin{code}
-tcWorker Nothing = returnNF_Tc Nothing
+tcWorker unf_env Nothing = returnNF_Tc Nothing
 
-tcWorker (Just (worker_name,_))
-  = tcLookupGlobalValueMaybe worker_name       `thenNF_Tc` \ maybe_worker_id ->
-    returnNF_Tc (trace_maybe maybe_worker_id)
+tcWorker unf_env (Just (worker_name,_))
+  = returnNF_Tc (trace_maybe maybe_worker_id)
   where
+    maybe_worker_id = tcExplicitLookupGlobal unf_env worker_name
+
        -- The trace is so we can see what's getting dropped
     trace_maybe Nothing  = pprTrace "tcWorker failed:" (ppr PprDebug worker_name) Nothing
-    trace_maybe (Just x) = Just (x, [])
+    trace_maybe (Just x) = Just x
 \end{code}
 
 For unfoldings we try to do the job lazily, so that we never type check
 an unfolding that isn't going to be looked at.
 
 \begin{code}
-tcUnfolding name core_expr
+tcUnfolding unf_env name core_expr
   = forkNF_Tc (
        recoverNF_Tc no_unfolding (
+               tcSetEnv unf_env $
                tcCoreExpr core_expr    `thenTc` \ core_expr' ->
                returnTc (mkUnfolding NoPragmaInfo core_expr')
     ))                 
@@ -261,7 +258,7 @@ tcCoreLamBndr (UfValBinder name ty) thing_inside
     
 tcCoreLamBndr (UfTyBinder name kind) thing_inside
   = let
-       tyvar = mkTyVar name kind
+       tyvar = mkSysTyVar (uniqueOf name) kind
     in
     tcExtendTyVarEnv [name] [(kindToTcKind kind, tyvar)] $
     thing_inside (TyBinder tyvar)