TyThing(..), TcTyThing(..), TcId,
-- Instance environment, and InstInfo type
- InstInfo(..), pprInstInfo, pprInstInfoDetails,
- simpleInstInfoTy, simpleInstInfoTyCon,
+ InstInfo(..), iDFunId, pprInstInfo, pprInstInfoDetails,
+ simpleInstInfoClsTy, simpleInstInfoTy, simpleInstInfoTyCon,
InstBindings(..),
-- Global environment
tcExtendGlobalEnv,
tcExtendGlobalValEnv,
- tcLookupGlobal,
+ tcLookupLocatedGlobal, tcLookupGlobal,
tcLookupGlobalId, tcLookupTyCon, tcLookupClass, tcLookupDataCon,
+ tcLookupLocatedGlobalId, tcLookupLocatedTyCon,
+ tcLookupLocatedClass,
- getInGlobalScope,
-
-- Local environment
- tcExtendTyVarKindEnv,
- tcExtendTyVarEnv, tcExtendTyVarEnv2,
- tcExtendLocalValEnv, tcExtendLocalValEnv2,
- tcLookup, tcLookupLocalIds,
+ tcExtendKindEnv, tcExtendKindEnvTvs,
+ tcExtendTyVarEnv, tcExtendTyVarEnv2,
+ tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2,
+ tcLookup, tcLookupLocated, tcLookupLocalIds,
tcLookupId, tcLookupTyVar,
lclEnvElts, getInLocalScope, findGlobals,
+ wrongThingErr, pprBinders,
tcExtendRecEnv, -- For knot-tying
checkWellStaged, spliceOK, bracketOK, tcMetaTy, thLevel,
topIdLvl,
- -- Arrow stuff
- checkProcLevel,
-
-- New Ids
newLocalName, newDFunName
) where
#include "HsVersions.h"
-import RnHsSyn ( RenamedMonoBinds, RenamedSig )
-import HsSyn ( RuleDecl(..), , HsTyVarBndr(..) )
+import HsSyn ( LRuleDecl, LHsBinds, LSig,
+ LHsTyVarBndr, HsTyVarBndr(..), pprLHsBinds )
import TcIface ( tcImportDecl )
+import IfaceEnv ( newGlobalBinder )
import TcRnMonad
-import TcMType ( zonkTcType, zonkTcTyVar, zonkTcTyVarsAndFV )
-import TcType ( Type, TcTyVar, TcTyVarSet,
- tyVarsOfType, tyVarsOfTypes, tcSplitDFunTy, mkGenTyConApp,
- getDFunTyKey, tcTyConAppTyCon, tyVarBindingInfo,
- tidyOpenType, tidyOpenTyVar
+import TcMType ( zonkTcType, zonkTcTyVarsAndFV )
+import TcType ( Type, TcKind, TcTyVar, TcTyVarSet, TcType,
+ tyVarsOfType, tyVarsOfTypes, mkGenTyConApp,
+ getDFunTyKey, tcTyConAppTyCon, tcGetTyVar, mkTyVarTy,
+ tidyOpenType
)
import qualified Type ( getTyVar_maybe )
import Id ( idName, isLocalId )
-import Var ( TyVar, Id, mkTyVar, idType )
+import Var ( TyVar, Id, idType, tyVarName )
import VarSet
import VarEnv
import RdrName ( extendLocalRdrEnv )
+import InstEnv ( Instance, DFunId, instanceDFunId, instanceHead )
import DataCon ( DataCon )
import TyCon ( TyCon )
import Class ( Class )
-import Name ( Name, NamedThing(..),
- getSrcLoc, mkInternalName, nameIsLocalOrFrom
- )
+import Name ( Name, NamedThing(..), getSrcLoc, nameIsLocalOrFrom )
import NameEnv
import OccName ( mkDFunOcc, occNameString )
-import HscTypes ( DFunId, extendTypeEnvList, lookupType,
- TyThing(..), tyThingId, tyThingTyCon, tyThingClass, tyThingDataCon,
+import HscTypes ( extendTypeEnvList, lookupType,
+ TyThing(..), tyThingId, tyThingDataCon,
ExternalPackageState(..) )
-import SrcLoc ( SrcLoc )
+import SrcLoc ( SrcLoc, Located(..) )
import Outputable
-import Maybe ( isJust )
\end{code}
%* *
%************************************************************************
+Using the Located versions (eg. tcLookupLocatedGlobal) is preferred,
+unless you know that the SrcSpan in the monad is already set to the
+span of the Name.
+
\begin{code}
-tcLookupGlobal :: Name -> TcM TyThing
+tcLookupLocatedGlobal :: Located Name -> TcM TyThing
-- c.f. IfaceEnvEnv.tcIfaceGlobal
+tcLookupLocatedGlobal name
+ = addLocM tcLookupGlobal name
+
+tcLookupGlobal :: Name -> TcM TyThing
tcLookupGlobal name
= do { env <- getGblEnv
; if nameIsLocalOrFrom (tcg_mod env) name
then -- It's defined in this module
case lookupNameEnv (tcg_type_env env) name of
Just thing -> return thing
- Nothing -> notFound "tcLookupGlobal" name
+ Nothing -> notFound name -- Panic!
else do -- It's imported
- { eps <- getEps
- ; hpt <- getHpt
+ { (eps,hpt) <- getEpsAndHpt
; case lookupType hpt (eps_PTE eps) name of
Just thing -> return thing
- Nothing -> do { traceIf (text "tcLookupGlobal" <+> ppr name)
- ; initIfaceTcRn (tcImportDecl name) }
+ Nothing -> tcImportDecl name
}}
-\end{code}
-\begin{code}
tcLookupGlobalId :: Name -> TcM Id
-- Never used for Haskell-source DataCons, hence no ADataCon case
tcLookupGlobalId name
tcLookupClass :: Name -> TcM Class
tcLookupClass name
- = tcLookupGlobal name `thenM` \ thing ->
- return (tyThingClass thing)
+ = tcLookupGlobal name `thenM` \ thing ->
+ case thing of
+ AClass cls -> return cls
+ other -> wrongThingErr "class" (AGlobal thing) name
tcLookupTyCon :: Name -> TcM TyCon
tcLookupTyCon name
- = tcLookupGlobal name `thenM` \ thing ->
- return (tyThingTyCon thing)
+ = tcLookupGlobal name `thenM` \ thing ->
+ case thing of
+ ATyCon tc -> return tc
+ other -> wrongThingErr "type constructor" (AGlobal thing) name
+
+tcLookupLocatedGlobalId :: Located Name -> TcM Id
+tcLookupLocatedGlobalId = addLocM tcLookupId
+
+tcLookupLocatedClass :: Located Name -> TcM Class
+tcLookupLocatedClass = addLocM tcLookupClass
+
+tcLookupLocatedTyCon :: Located Name -> TcM TyCon
+tcLookupLocatedTyCon = addLocM tcLookupTyCon
\end{code}
%************************************************************************
= tcExtendGlobalEnv [AnId id | id <- ids] thing_inside
\end{code}
-A variety of global lookups, when we know what we are looking for.
-
\begin{code}
-getInGlobalScope :: TcM (Name -> Bool)
--- Get all things in the global environment; used for deciding what
--- rules to suck in. Anything defined in this module (nameIsLocalOrFrom)
--- is certainly in the envt, so we don't bother to look.
-getInGlobalScope
- = do { mod <- getModule
- ; eps <- getEps
- ; hpt <- getHpt
- ; return (\n -> nameIsLocalOrFrom mod n ||
- isJust (lookupType hpt (eps_PTE eps) n)) }
-\end{code}
-
-
-\begin{code}
-tcExtendRecEnv :: [(Name,TyThing)] -- Global bindings
- -> [(Name,TcTyThing)] -- Local bindings
- -> TcM r -> TcM r
--- Extend both local and global environments for the type/class knot tying game
-tcExtendRecEnv gbl_stuff lcl_stuff thing_inside
- = do { (gbl_env, lcl_env) <- getEnvs
- ; let { ge' = extendNameEnvList (tcg_type_env gbl_env) gbl_stuff
- ; le' = extendNameEnvList (tcl_env lcl_env) lcl_stuff }
- ; setEnvs (gbl_env {tcg_type_env = ge'}, lcl_env {tcl_env = le'})
- thing_inside }
+tcExtendRecEnv :: [(Name,TyThing)] -> TcM r -> TcM r
+-- Extend the global environments for the type/class knot tying game
+tcExtendRecEnv gbl_stuff thing_inside
+ = updGblEnv upd thing_inside
+ where
+ upd env = env { tcg_type_env = extend (tcg_type_env env) }
+ extend env = extendNameEnvList env gbl_stuff
\end{code}
%************************************************************************
\begin{code}
+tcLookupLocated :: Located Name -> TcM TcTyThing
+tcLookupLocated = addLocM tcLookup
+
tcLookup :: Name -> TcM TcTyThing
tcLookup name
= getLclEnv `thenM` \ local_env ->
Nothing -> tcLookupGlobal name `thenM` \ thing ->
returnM (AGlobal thing)
-tcLookupTyVar :: Name -> TcM Id
+tcLookupTyVar :: Name -> TcM TcTyVar
tcLookupTyVar name
= tcLookup name `thenM` \ thing ->
case thing of
- ATyVar tv -> returnM tv
- other -> pprPanic "tcLookupTyVar" (ppr name)
+ ATyVar _ ty -> returnM (tcGetTyVar "tcLookupTyVar" ty)
+ other -> pprPanic "tcLookupTyVar" (ppr name)
tcLookupId :: Name -> TcM Id
-- Used when we aren't interested in the binding level
tcLookupId name
= tcLookup name `thenM` \ thing ->
case thing of
- ATcId tc_id _ _ -> returnM tc_id
+ ATcId tc_id _ -> returnM tc_id
AGlobal (AnId id) -> returnM id
other -> pprPanic "tcLookupId" (ppr name)
where
lookup lenv lvl name
= case lookupNameEnv lenv name of
- Just (ATcId id lvl1 _) -> ASSERT( lvl == lvl1 ) id
- other -> pprPanic "tcLookupLocalIds" (ppr name)
+ Just (ATcId id lvl1) -> ASSERT( lvl == lvl1 ) id
+ other -> pprPanic "tcLookupLocalIds" (ppr name)
lclEnvElts :: TcLclEnv -> [TcTyThing]
lclEnvElts env = nameEnvElts (tcl_env env)
\end{code}
\begin{code}
-tcExtendTyVarKindEnv :: [HsTyVarBndr Name] -> TcM r -> TcM r
--- The tyvars are all kinded
-tcExtendTyVarKindEnv tvs thing_inside
+tcExtendKindEnv :: [(Name, TcKind)] -> TcM r -> TcM r
+tcExtendKindEnv things thing_inside
= updLclEnv upd thing_inside
where
upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
- extend env = extendNameEnvList env [(n, ATyVar (mkTyVar n k))
- | KindedTyVar n k <- tvs]
- -- No need to extend global tyvars for kind checking
+ extend env = extendNameEnvList env [(n, AThing k) | (n,k) <- things]
+
+tcExtendKindEnvTvs :: [LHsTyVarBndr Name] -> TcM r -> TcM r
+tcExtendKindEnvTvs bndrs thing_inside
+ = updLclEnv upd thing_inside
+ where
+ upd lcl_env = lcl_env { tcl_env = extend (tcl_env lcl_env) }
+ extend env = extendNameEnvList env pairs
+ pairs = [(n, AThing k) | L _ (KindedTyVar n k) <- bndrs]
tcExtendTyVarEnv :: [TyVar] -> TcM r -> TcM r
tcExtendTyVarEnv tvs thing_inside
- = tc_extend_tv_env [(getName tv, ATyVar tv) | tv <- tvs] tvs thing_inside
+ = tcExtendTyVarEnv2 [(tyVarName tv, mkTyVarTy tv) | tv <- tvs] thing_inside
-tcExtendTyVarEnv2 :: [(TyVar,TcTyVar)] -> TcM r -> TcM r
-tcExtendTyVarEnv2 tv_pairs thing_inside
- = tc_extend_tv_env [(getName tv1, ATyVar tv2) | (tv1,tv2) <- tv_pairs]
- [tv | (_,tv) <- tv_pairs]
- thing_inside
-
-tc_extend_tv_env binds tyvars thing_inside
+tcExtendTyVarEnv2 :: [(Name,TcType)] -> TcM r -> TcM r
+tcExtendTyVarEnv2 binds thing_inside
= getLclEnv `thenM` \ env@(TcLclEnv {tcl_env = le,
tcl_tyvars = gtvs,
tcl_rdr = rdr_env}) ->
let
- le' = extendNameEnvList le binds
rdr_env' = extendLocalRdrEnv rdr_env (map fst binds)
- new_tv_set = mkVarSet tyvars
+ new_tv_set = tyVarsOfTypes (map snd binds)
+ le' = extendNameEnvList le [(name, ATyVar name ty) | (name, ty) <- binds]
in
-- It's important to add the in-scope tyvars to the global tyvar set
-- as well. Consider
\begin{code}
-tcExtendLocalValEnv :: [TcId] -> TcM a -> TcM a
-tcExtendLocalValEnv ids thing_inside
- = getLclEnv `thenM` \ env ->
- let
- extra_global_tyvars = tyVarsOfTypes [idType id | id <- ids]
- th_lvl = thLevel (tcl_th_ctxt env)
- proc_lvl = proc_level (tcl_arrow_ctxt env)
- extra_env = [(idName id, ATcId id th_lvl proc_lvl) | id <- ids]
- le' = extendNameEnvList (tcl_env env) extra_env
- rdr_env' = extendLocalRdrEnv (tcl_rdr env) (map idName ids)
- in
- tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars `thenM` \ gtvs' ->
- setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside
-
-tcExtendLocalValEnv2 :: [(Name,TcId)] -> TcM a -> TcM a
-tcExtendLocalValEnv2 names_w_ids thing_inside
+tcExtendIdEnv :: [TcId] -> TcM a -> TcM a
+-- Invariant: the TcIds are fully zonked. Reasons:
+-- (a) The kinds of the forall'd type variables are defaulted
+-- (see Kind.defaultKind, done in zonkQuantifiedTyVar)
+-- (b) There are no via-Indirect occurrences of the bound variables
+-- in the types, because instantiation does not look through such things
+-- (c) The call to tyVarsOfTypes is ok without looking through refs
+tcExtendIdEnv ids thing_inside = tcExtendIdEnv2 [(idName id, id) | id <- ids] thing_inside
+
+tcExtendIdEnv1 :: Name -> TcId -> TcM a -> TcM a
+tcExtendIdEnv1 name id thing_inside = tcExtendIdEnv2 [(name,id)] thing_inside
+
+tcExtendIdEnv2 :: [(Name,TcId)] -> TcM a -> TcM a
+-- Invariant: the TcIds are fully zonked (see tcExtendIdEnv above)
+tcExtendIdEnv2 names_w_ids thing_inside
= getLclEnv `thenM` \ env ->
let
extra_global_tyvars = tyVarsOfTypes [idType id | (name,id) <- names_w_ids]
th_lvl = thLevel (tcl_th_ctxt env)
- proc_lvl = proc_level (tcl_arrow_ctxt env)
- extra_env = [(name, ATcId id th_lvl proc_lvl) | (name,id) <- names_w_ids]
+ extra_env = [(name, ATcId id th_lvl) | (name,id) <- names_w_ids]
le' = extendNameEnvList (tcl_env env) extra_env
rdr_env' = extendLocalRdrEnv (tcl_rdr env) (map fst names_w_ids)
in
ignore_it ty = not (tvs `intersectsVarSet` tyVarsOfType ty)
-----------------------
-find_thing ignore_it tidy_env (ATcId id _ _)
+find_thing ignore_it tidy_env (ATcId id _)
= zonkTcType (idType id) `thenM` \ id_ty ->
if ignore_it id_ty then
returnM (tidy_env, Nothing)
in
returnM (tidy_env', Just msg)
-find_thing ignore_it tidy_env (ATyVar tv)
- = zonkTcTyVar tv `thenM` \ tv_ty ->
+find_thing ignore_it tidy_env (ATyVar tv ty)
+ = zonkTcType ty `thenM` \ tv_ty ->
if ignore_it tv_ty then
returnM (tidy_env, Nothing)
else let
- (tidy_env1, tv1) = tidyOpenTyVar tidy_env tv
- (tidy_env2, tidy_ty) = tidyOpenType tidy_env1 tv_ty
- msg = sep [ppr tv1 <+> eq_stuff, nest 2 bound_at]
+ -- The name tv is scoped, so we don't need to tidy it
+ (tidy_env1, tidy_ty) = tidyOpenType tidy_env tv_ty
+ msg = sep [ptext SLIT("Scoped type variable") <+> quotes (ppr tv) <+> eq_stuff, nest 2 bound_at]
eq_stuff | Just tv' <- Type.getTyVar_maybe tv_ty,
- tv == tv' = empty
+ getOccName tv == getOccName tv' = empty
| otherwise = equals <+> ppr tidy_ty
-- It's ok to use Type.getTyVar_maybe because ty is zonked by now
-
- bound_at = tyVarBindingInfo tv
+ bound_at = parens $ ptext SLIT("bound at:") <+> ppr (getSrcLoc tv)
in
- returnM (tidy_env2, Just msg)
+ returnM (tidy_env1, Just msg)
\end{code}
%************************************************************************
\begin{code}
-tcExtendRules :: [RuleDecl Id] -> TcM a -> TcM a
+tcExtendRules :: [LRuleDecl Id] -> TcM a -> TcM a
-- Just pop the new rules into the EPS and envt resp
-- All the rules come from an interface file, not soruce
-- Nevertheless, some may be for this module, if we read
%************************************************************************
%* *
- Arrow notation proc levels
-%* *
-%************************************************************************
-
-\begin{code}
-checkProcLevel :: TcId -> ProcLevel -> TcM ()
-checkProcLevel id id_lvl
- = do { banned <- getBannedProcLevels
- ; checkTc (not (id_lvl `elem` banned))
- (procLevelErr id id_lvl) }
-
-procLevelErr id id_lvl
- = hang (ptext SLIT("Command-bound variable") <+> quotes (ppr id) <+> ptext SLIT("is not in scope here"))
- 4 (ptext SLIT("Reason: it is used in the left argument of (-<)"))
-\end{code}
-
-
-%************************************************************************
-%* *
Meta level
%* *
%************************************************************************
topIdLvl :: Id -> ThLevel
-- Globals may either be imported, or may be from an earlier "chunk"
-- (separated by declaration splices) of this module. The former
--- *can* be used inside a top-level splice, but the latter cannot.
+-- *can* be used inside a top-level splice, but the latter cannot.
-- Hence we give the former impLevel, but the latter topLevel
-- E.g. this is bad:
-- x = [| foo |]
-- Indicates the legal transitions on bracket( [| |] ).
bracketOK :: ThStage -> Maybe ThLevel
bracketOK (Brack _ _ _) = Nothing -- Bracket illegal inside a bracket
-bracketOK stage = (Just (thLevel stage + 1))
+bracketOK stage = Just (thLevel stage + 1)
-- Indicates the legal transitions on splice($).
spliceOK :: ThStage -> Maybe ThLevel
%************************************************************************
%* *
-\subsection{Making new Ids}
-%* *
-%************************************************************************
-
-Constructing new Ids
-
-\begin{code}
-newLocalName :: Name -> TcM Name
-newLocalName name -- Make a clone
- = newUnique `thenM` \ uniq ->
- returnM (mkInternalName uniq (getOccName name) (getSrcLoc name))
-\end{code}
-
-Make a name for the dict fun for an instance decl. It's a *local*
-name for the moment. The CoreTidy pass will externalise it. Even in
---make and ghci stuff, we rebuild the instance environment each time,
-so the dfun id is internal to begin with, and external when compiling
-other modules
-
-\begin{code}
-newDFunName :: Class -> [Type] -> SrcLoc -> TcM Name
-newDFunName clas (ty:_) loc
- = newUnique `thenM` \ uniq ->
- returnM (mkInternalName uniq (mkDFunOcc dfun_string) loc)
- where
- -- Any string that is somewhat unique will do
- dfun_string = occNameString (getOccName clas) ++ occNameString (getDFunTyKey ty)
-
-newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
-\end{code}
-
-
-%************************************************************************
-%* *
\subsection{The InstInfo type}
%* *
%************************************************************************
\begin{code}
data InstInfo
= InstInfo {
- iDFunId :: DFunId, -- The dfun id
- iBinds :: InstBindings
+ iSpec :: Instance, -- Includes the dfun id. Its forall'd type
+ iBinds :: InstBindings -- variables scope over the stuff in InstBindings!
}
+iDFunId :: InstInfo -> DFunId
+iDFunId info = instanceDFunId (iSpec info)
+
data InstBindings
= VanillaInst -- The normal case
- RenamedMonoBinds -- Bindings
- [RenamedSig] -- User pragmas recorded for generating
+ (LHsBinds Name) -- Bindings
+ [LSig Name] -- User pragmas recorded for generating
-- specialised instances
| NewTypeDerived -- Used for deriving instances of newtypes, where the
pprInstInfoDetails info = pprInstInfo info $$ nest 2 (details (iBinds info))
where
- details (VanillaInst b _) = ppr b
+ details (VanillaInst b _) = pprLHsBinds b
details (NewTypeDerived _) = text "Derived from the representation type"
+simpleInstInfoClsTy :: InstInfo -> (Class, Type)
+simpleInstInfoClsTy info = case instanceHead (iSpec info) of
+ (_, _, cls, [ty]) -> (cls, ty)
+
simpleInstInfoTy :: InstInfo -> Type
-simpleInstInfoTy info = case tcSplitDFunTy (idType (iDFunId info)) of
- (_, _, _, [ty]) -> ty
+simpleInstInfoTy info = snd (simpleInstInfoClsTy info)
simpleInstInfoTyCon :: InstInfo -> TyCon
-- Gets the type constructor for a simple instance declaration,
simpleInstInfoTyCon inst = tcTyConAppTyCon (simpleInstInfoTy inst)
\end{code}
+Make a name for the dict fun for an instance decl. It's an *external*
+name, like otber top-level names, and hence must be made with newGlobalBinder.
+
+\begin{code}
+newDFunName :: Class -> [Type] -> SrcLoc -> TcM Name
+newDFunName clas (ty:_) loc
+ = do { index <- nextDFunIndex
+ ; is_boot <- tcIsHsBoot
+ ; mod <- getModule
+ ; let info_string = occNameString (getOccName clas) ++
+ occNameString (getDFunTyKey ty)
+ dfun_occ = mkDFunOcc info_string is_boot index
+
+ ; newGlobalBinder mod dfun_occ Nothing loc }
+
+newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc)
+\end{code}
+
%************************************************************************
%* *
%************************************************************************
\begin{code}
-notFound wheRe name = failWithTc (text wheRe <> colon <+> quotes (ppr name) <+>
- ptext SLIT("is not in scope"))
+pprBinders :: [Name] -> SDoc
+-- Used in error messages
+-- Use quotes for a single one; they look a bit "busy" for several
+pprBinders [bndr] = quotes (ppr bndr)
+pprBinders bndrs = pprWithCommas ppr bndrs
+
+notFound name
+ = failWithTc (ptext SLIT("GHC internal error:") <+> quotes (ppr name) <+>
+ ptext SLIT("is not in scope"))
+
+wrongThingErr expected thing name
+ = failWithTc (pprTcTyThingCategory thing <+> quotes (ppr name) <+>
+ ptext SLIT("used as a") <+> text expected)
\end{code}