[project @ 1996-03-19 08:58:34 by partain]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcMonoType.lhs
index 9c68a7d..4ed8e50 100644 (file)
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[TcMonoType]{Typechecking user-specified @MonoTypes@}
 
 \begin{code}
 #include "HsVersions.h"
 
-module TcMonoType ( tcMonoType, tcInstanceType ) where
+module TcMonoType ( tcPolyType, tcMonoType, tcMonoTypeKind, tcContext ) where
 
-IMPORT_Trace           -- ToDo: rm (debugging)
-import Outputable
-import Pretty
+import Ubiq{-uitous-}
 
-import TcMonad         -- typechecking monad machinery
-import AbsSyn          -- the stuff being typechecked
-
-#ifndef DPH
-import AbsPrel         ( mkListTy, mkTupleTy, mkFunTy )
-#else
-import AbsPrel         ( mkListTy, mkTupleTy, mkFunTy, mkProcessorTy, mkPodTy )
-#endif {- Data Parallel Haskell -}
-import AbsUniType      ( applySynTyCon, applyNonSynTyCon, mkDictTy,
-                         getTyConArity, isSynTyCon, isTyVarTemplateTy,
-                         getUniDataTyCon_maybe, maybeUnpackFunTy
-                         IF_ATTACK_PRAGMAS(COMMA pprTyCon COMMA pprUniType)
-                         IF_ATTACK_PRAGMAS(COMMA cmpUniType)
+import HsSyn           ( PolyType(..), MonoType(..), Fake )
+import RnHsSyn         ( RenamedPolyType(..), RenamedMonoType(..), 
+                         RenamedContext(..)
                        )
-import UniType         ( UniType(..) ) -- ******** CHEATING **** could be undone
-import TyCon           --( TyCon(..) ) -- ditto, only more so
 
-import CE              ( lookupCE, CE(..) )
-import CmdLineOpts     ( GlobalSwitch(..) )
-import Errors          ( confusedNameErr, tyConArityErr, instTypeErr,
-                         Error(..)
+
+import TcMonad
+import TcEnv           ( tcLookupTyVar, tcLookupClass, tcLookupTyCon, 
+                         tcExtendTyVarEnv, tcTyVarScope
+                       )
+import TcKind          ( TcKind, mkTcTypeKind, mkBoxedTypeKind,
+                         mkTcArrowKind, unifyKind, newKindVar,
+                         kindToTcKind
                        )
-import Maybes          ( Maybe(..) )
-import TcPolyType      ( tcPolyType )
-import TCE             ( lookupTCE, TCE(..), UniqFM )
-import TVE             ( lookupTVE, TVE(..) )
-import Util
+import ErrUtils                ( arityErr )
+import Type            ( GenType, Type(..), ThetaType(..), 
+                         mkTyVarTy, mkTyConTy, mkFunTy, mkAppTy,
+                         mkSigmaTy
+                       )
+import TyVar           ( GenTyVar, TyVar(..), mkTyVar )
+import PrelInfo                ( mkListTy, mkTupleTy )
+import Type            ( mkDictTy )
+import Class           ( cCallishClassKeys )
+import Unique          ( Unique )
+import Name            ( Name(..), getNameShortName, isTyConName, getSynNameArity )
+import PprStyle
+import Pretty
+import Util            ( zipWithEqual, panic )
 \end{code}
 
+
+tcMonoType and tcMonoTypeKind
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+tcMonoType checks that the type really is of kind Type!
+
 \begin{code}
-tcMonoType :: CE -> TCE -> TVE -> RenamedMonoType -> Baby_TcM UniType
-
-tcMonoType rec_ce rec_tce tve (MonoTyVar name)
-  = returnB_Tc (lookupTVE tve name)
-
-tcMonoType rec_ce rec_tce tve (ListMonoTy ty)
-  = tcMonoType rec_ce rec_tce tve ty   `thenB_Tc` \ tau_ty ->
-    returnB_Tc (mkListTy tau_ty)
-
-tcMonoType rec_ce rec_tce tve (TupleMonoTy tys)
-  = mapB_Tc (tcPolyType rec_ce rec_tce tve) tys        `thenB_Tc` \ tau_tys ->
-    returnB_Tc (mkTupleTy (length tau_tys) tau_tys)
-
-tcMonoType rec_ce rec_tce tve (FunMonoTy ty1 ty2)
-  = tcMonoType rec_ce rec_tce tve ty1  `thenB_Tc` \ tau_ty1 ->
-    tcMonoType rec_ce rec_tce tve ty2  `thenB_Tc` \ tau_ty2 ->
-    returnB_Tc (mkFunTy tau_ty1 tau_ty2)
-
-tcMonoType rec_ce rec_tce tve (MonoTyCon name@(WiredInTyCon tycon) tys)
-  = let 
-       arity        = getTyConArity tycon
-       is_syn_tycon = isSynTyCon tycon
-    in
-    tcMonoType_help rec_ce rec_tce tve name tycon arity is_syn_tycon tys
-
-tcMonoType rec_ce rec_tce tve (MonoTyCon name@(PreludeTyCon _ _ arity is_data_tycon) tys)
-  = tcMonoType_help rec_ce rec_tce tve name
-                   (lookupTCE rec_tce name)
-                   arity (not is_data_tycon) tys
-
-
-tcMonoType rec_ce rec_tce tve (MonoTyCon name@(OtherTyCon _ _ arity is_data_tycon _) tys)
-  = tcMonoType_help rec_ce rec_tce tve name
-                   (lookupTCE rec_tce name)
-                   arity (not is_data_tycon) tys
-
-tcMonoType rec_ce rec_tce tve (MonoTyCon bad_name tys)
-  = getSrcLocB_Tc              `thenB_Tc` \ locn ->
-    failB_Tc (confusedNameErr
-               "Bad name for a type constructor (a class, or a Prelude name?)"
-               bad_name locn)
-
--- two for unfoldings only:
-tcMonoType rec_ce rec_tce tve (MonoDict c ty)
-  = tcMonoType rec_ce rec_tce tve ty   `thenB_Tc` \ new_ty ->
-    let
-       clas = lookupCE rec_ce c
-    in
-    returnB_Tc (mkDictTy clas new_ty)
-
-tcMonoType rec_ce rec_tce tve (MonoTyVarTemplate tv_tmpl)
-  = returnB_Tc (lookupTVE tve tv_tmpl)
-
-#ifdef DPH
-tcMonoType ce tce tve (MonoTyProc tys ty)
-  = tcMonoTypes ce tce tve tys `thenB_Tc` \ tau_tys ->
-    tcMonoType ce tce tve ty   `thenB_Tc` \ tau_ty  ->
-    returnB_Tc (mkProcessorTy tau_tys tau_ty)
-
-tcMonoType ce tce tve (MonoTyPod ty)
-  = tcMonoType ce tce tve ty   `thenB_Tc` \ tau_ty  ->
-    returnB_Tc (mkPodTy tau_ty)
-#endif {- Data Parallel Haskell -}
-
-#ifdef DEBUG
-tcMonoType rec_ce rec_tce tve bad_ty
-  = pprPanic "tcMonoType:" (ppr PprShowAll bad_ty)
-#endif
+tcMonoType :: RenamedMonoType -> TcM s Type
+
+tcMonoType ty
+  = tcMonoTypeKind ty                  `thenTc` \ (kind,ty) ->
+    unifyKind kind mkTcTypeKind                `thenTc_`
+    returnTc ty
 \end{code}
 
+tcMonoTypeKind does the real work.  It returns a kind and a type.
+
 \begin{code}
-tcMonoType_help rec_ce rec_tce tve name tycon arity is_syn_tycon tys
-  = tcMonoTypes rec_ce rec_tce tve tys `thenB_Tc`    \ tau_tys ->
-    let         cur_arity = length tys  in
-    getSrcLocB_Tc                      `thenB_Tc` \ loc ->
-
-    checkB_Tc (arity /= cur_arity)
-          (tyConArityErr name arity cur_arity loc) `thenB_Tc_`
-
-    returnB_Tc (if is_syn_tycon then
-                applySynTyCon  tycon tau_tys
-             else
-                applyNonSynTyCon tycon tau_tys)
-
--- also not exported
-tcMonoTypes rec_ce rec_tce tve monotypes
-   = mapB_Tc (tcMonoType rec_ce rec_tce tve) monotypes
+tcMonoTypeKind :: RenamedMonoType -> TcM s (TcKind s, Type)
+
+tcMonoTypeKind (MonoTyVar name)
+  = tcLookupTyVar name `thenNF_Tc` \ (kind,tyvar) ->
+    returnTc (kind, mkTyVarTy tyvar)
+    
+
+tcMonoTypeKind (MonoListTy ty)
+  = tcMonoType ty      `thenTc` \ tau_ty ->
+    returnTc (mkTcTypeKind, mkListTy tau_ty)
+
+tcMonoTypeKind (MonoTupleTy tys)
+  = mapTc tcMonoType  tys      `thenTc` \ tau_tys ->
+    returnTc (mkTcTypeKind, mkTupleTy (length tys) tau_tys)
+
+tcMonoTypeKind (MonoFunTy ty1 ty2)
+  = tcMonoType ty1     `thenTc` \ tau_ty1 ->
+    tcMonoType ty2     `thenTc` \ tau_ty2 ->
+    returnTc (mkTcTypeKind, mkFunTy tau_ty1 tau_ty2)
+
+tcMonoTypeKind (MonoTyApp name tys)
+  = mapAndUnzipTc tcMonoTypeKind tys   `thenTc`    \ (arg_kinds, arg_tys) ->
+
+    tc_mono_name name                  `thenNF_Tc` \ (fun_kind, fun_ty) ->
+
+    newKindVar                         `thenNF_Tc` \ result_kind ->
+    unifyKind fun_kind (foldr mkTcArrowKind result_kind arg_kinds)     `thenTc_`
+
+       -- Check for saturated application in the special case of
+       -- type synoyms.  Here the renamer has kindly attached the
+       -- arity to the Name.
+    synArityCheck name (length tys)    `thenTc_`
+
+    returnTc (result_kind, foldl mkAppTy fun_ty arg_tys)
+
+-- for unfoldings only:
+tcMonoTypeKind (MonoForAllTy tyvars_w_kinds ty)
+  = tcExtendTyVarEnv tyvar_names (tc_kinds `zip` tyvars) (
+       tcMonoTypeKind ty               `thenTc` \ (kind, ty') ->
+       unifyKind kind mkTcTypeKind     `thenTc_`
+       returnTc (mkTcTypeKind, ty')
+    )
+  where
+    (tyvar_names, kinds) = unzip tyvars_w_kinds
+    tyvars   = zipWithEqual mk_tyvar tyvar_names kinds
+    tc_kinds = map kindToTcKind kinds
+    mk_tyvar name kind = mkTyVar (getNameShortName name) (getItsUnique name) kind
+
+-- for unfoldings only:
+tcMonoTypeKind (MonoDictTy class_name ty)
+  = tcMonoTypeKind ty                  `thenTc` \ (arg_kind, arg_ty) ->
+    tcLookupClass class_name           `thenNF_Tc` \ (class_kind, clas) ->
+    unifyKind class_kind arg_kind      `thenTc_`
+    returnTc (mkTcTypeKind, mkDictTy clas arg_ty)
+
+
+tc_mono_name :: Name -> NF_TcM s (TcKind s, Type)
+tc_mono_name name@(Short _ _)          -- Must be a type variable
+  = tcLookupTyVar name                 `thenNF_Tc` \ (kind,tyvar) ->
+    returnNF_Tc (kind, mkTyVarTy tyvar)
+
+tc_mono_name name | isTyConName name   -- Must be a type constructor
+  = tcLookupTyCon name                 `thenNF_Tc` \ (kind,tycon) ->
+    returnNF_Tc (kind, mkTyConTy tycon)
+       
+tc_mono_name name                      -- Renamer should have got it right
+  = panic ("tc_mono_name:" ++ ppShow 1000 (ppr PprDebug name))
 \end{code}
 
-@tcInstanceType@ checks the type {\em and} its syntactic constraints:
-it must normally look like: @instance Foo (Tycon a b c ...) ...@
-(We're checking the @Tycon a b c ...@ part here...)
 
-The exceptions to this syntactic checking: (1)~if the @GlasgowExts@
-flag is on, or (2)~the instance is imported (they must have been
-compiled elsewhere).  In these cases, we let them go through anyway.
+Contexts
+~~~~~~~~
+\begin{code}
+
+tcContext :: RenamedContext -> TcM s ThetaType
+tcContext context = mapTc tcClassAssertion context
+
+tcClassAssertion (class_name, tyvar_name)
+  = checkTc (canBeUsedInContext class_name)
+           (naughtyCCallContextErr class_name) `thenTc_`
+
+    tcLookupClass class_name           `thenNF_Tc` \ (class_kind, clas) ->
+    tcLookupTyVar tyvar_name           `thenNF_Tc` \ (tyvar_kind, tyvar) ->
 
-We can also have instances for functions: @instance Foo (a -> b) ...@.
+    unifyKind class_kind tyvar_kind    `thenTc_`
+
+    returnTc (clas, mkTyVarTy tyvar)
+\end{code}
+
+HACK warning: Someone discovered that @_CCallable@ and @_CReturnable@
+could be used in contexts such as:
+\begin{verbatim}
+foo :: _CCallable a => a -> PrimIO Int
+\end{verbatim}
+
+Doing this utterly wrecks the whole point of introducing these
+classes so we specifically check that this isn't being done.
 
 \begin{code}
-tcInstanceType :: CE -> TCE -> TVE
-              -> Bool{-True <=> from this module-} -> SrcLoc
-              -> RenamedMonoType
-              -> Baby_TcM UniType
-
-tcInstanceType ce tce tve from_here locn mono_ty
-  = tcMonoType ce tce tve mono_ty      `thenB_Tc` \ tau_ty  ->
-    let
-       (naughty, unkosher) = bad_shape tau_ty
-    in
-    getSwitchCheckerB_Tc               `thenB_Tc` \ sw_chkr ->
-    checkB_Tc
-       (if not from_here || sw_chkr GlasgowExts then -- no "shape" checking
-           naughty
-        else
-           naughty || unkosher
-       )
-       (instTypeErr tau_ty locn)       `thenB_Tc_`
-    returnB_Tc tau_ty
+canBeUsedInContext :: Name -> Bool
+canBeUsedInContext (ClassName uniq _ _) = not (uniq `elem` cCallishClassKeys)
+canBeUsedInContext other               = True
+\end{code}
+
+
+Polytypes
+~~~~~~~~~
+\begin{code}
+tcPolyType :: RenamedPolyType -> TcM s Type
+tcPolyType (HsForAllTy tyvar_names context ty)
+  = tcTyVarScope tyvar_names (\ tyvars ->
+       tcContext context       `thenTc` \ theta ->
+       tcMonoType ty           `thenTc` \ tau ->
+       returnTc (mkSigmaTy tyvars theta tau)
+    )
+\end{code}
+
+Auxilliary functions
+~~~~~~~~~~~~~~~~~~~~
+\begin{code}
+synArityCheck :: Name -> Int -> TcM s ()
+synArityCheck name n_args
+  = case getSynNameArity name of
+       Just arity | arity /= n_args -> failTc (err arity)
+       other                        -> returnTc ()
   where
-    -- "naughty" if the type is really unacceptable, no
-    -- matter what (e.g., a type synonym); "unkosher" if
-    -- the Haskell report forbids it, but we allow it through
-    -- under -fglasgow-exts.
-
-    bad_shape ty
-      = if (is_syn_type ty) then
-          (True, bottom)
-       else case (getUniDataTyCon_maybe ty) of
-         Just (_,tys,_) -> (False, not (all isTyVarTemplateTy tys))
-         Nothing        -> case maybeUnpackFunTy ty of
-                             Just (t1, t2) -> (False,
-                                               not (all isTyVarTemplateTy [t1, t2]))
-                             Nothing       -> (True, bottom)
-      where
-       bottom = panic "bad_shape"
-
-       is_syn_type ty -- ToDo: move to AbsUniType (or friend)?
-         = case ty of
-             UniSyn _ _ _ -> True
-             _ -> False
+    err arity = arityErr "Type synonym constructor" name arity n_args
+\end{code}
+
+Errors and contexts
+~~~~~~~~~~~~~~~~~~~
+\begin{code}
+naughtyCCallContextErr clas_name sty
+  = ppSep [ppStr "Can't use class", ppr sty clas_name, ppStr "in a context"]
 \end{code}