X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcEnv.lhs;h=4f48f7fde58d3294ed032fb4a655f0371daf1bdc;hp=e1b9bd31b70c912cf74f7b61754aa43d89c77fb6;hb=5822cb8d13aa3c05d2b46b4510c13d94b902eb21;hpb=84923cc7de2a93c22a2f72daf9ac863959efae13 diff --git a/compiler/typecheck/TcEnv.lhs b/compiler/typecheck/TcEnv.lhs index e1b9bd3..4f48f7f 100644 --- a/compiler/typecheck/TcEnv.lhs +++ b/compiler/typecheck/TcEnv.lhs @@ -22,6 +22,7 @@ module TcEnv( -- Local environment tcExtendKindEnv, tcExtendKindEnvTvs, tcExtendTyVarEnv, tcExtendTyVarEnv2, + tcExtendGhciEnv, tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2, tcLookup, tcLookupLocated, tcLookupLocalIds, tcLookupId, tcLookupTyVar, getScopedTyVarBinds, @@ -42,7 +43,7 @@ module TcEnv( topIdLvl, -- New Ids - newLocalName, newDFunName, newFamInstTyConName + newLocalName, newDFunName, newFamInstTyConName, ) where #include "HsVersions.h" @@ -54,8 +55,8 @@ import TcRnMonad import TcMType import TcType import TcGadt +-- import TcSuspension import qualified Type -import Id import Var import VarSet import VarEnv @@ -64,6 +65,8 @@ import InstEnv import FamInstEnv import DataCon import TyCon +import TypeRep +import Coercion import Class import Name import PrelNames @@ -72,6 +75,7 @@ import OccName import HscTypes import SrcLoc import Outputable +import Maybes \end{code} @@ -159,23 +163,34 @@ tcLookupLocatedClass = addLocM tcLookupClass tcLookupLocatedTyCon :: Located Name -> TcM TyCon tcLookupLocatedTyCon = addLocM tcLookupTyCon --- Look up the representation tycon of a family instance. --- Return the rep tycon and the corresponding rep args -tcLookupFamInst :: TyCon -> [Type] -> TcM (TyCon, [Type]) +-- Look up the instance tycon of a family instance. +-- +-- The match must be unique - ie, match exactly one instance - but the +-- type arguments used for matching may be more specific than those of +-- the family instance declaration. +-- +-- Return the instance tycon and its type instance. For example, if we have +-- +-- tcLookupFamInst 'T' '[Int]' yields (':R42T', 'Int') +-- +-- then we have a coercion (ie, type instance of family instance coercion) +-- +-- :Co:R42T Int :: T [Int] ~ :R42T Int +-- +-- which implies that :R42T was declared as 'data instance T [a]'. +-- +tcLookupFamInst :: TyCon -> [Type] -> TcM (Maybe (TyCon, [Type])) tcLookupFamInst tycon tys | not (isOpenTyCon tycon) - = return (tycon, tys) + = return Nothing | otherwise = do { env <- getGblEnv ; eps <- getEps ; let instEnv = (eps_fam_inst_env eps, tcg_fam_inst_env env) ; case lookupFamInstEnv instEnv tycon tys of - [(subst,fam_inst)] -> return (rep_tc, substTyVars subst (tyConTyVars rep_tc)) - where -- NB: assumption is that (tyConTyVars rep_tc) is in - -- the domain of the substitution - rep_tc = famInstTyCon fam_inst - - other -> famInstNotFound tycon tys other + [(fam_inst, rep_tys)] -> return $ Just (famInstTyCon fam_inst, + rep_tys) + other -> return Nothing } \end{code} @@ -322,12 +337,6 @@ getScopedTyVarBinds \begin{code} 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 @@ -336,25 +345,48 @@ 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 = tcTyVarsOfTypes [idType id | (_,id) <- names_w_ids] - th_lvl = thLevel (tcl_th_ctxt env) - extra_env = [ (name, ATcId { tct_id = id, - tct_level = th_lvl, - tct_type = id_ty, - tct_co = if isRefineableTy id_ty - then Just idHsWrapper - else Nothing }) - | (name,id) <- names_w_ids, let id_ty = idType id] - le' = extendNameEnvList (tcl_env env) extra_env - rdr_env' = extendLocalRdrEnv (tcl_rdr env) [name | (name,_) <- names_w_ids] - in - traceTc (text "env2") `thenM_` - traceTc (text "env3" <+> ppr extra_env) `thenM_` - tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars `thenM` \ gtvs' -> - (traceTc (text "env4") `thenM_` - setLclEnv (env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'}) thing_inside) + = do { env <- getLclEnv + ; tc_extend_local_id_env env (thLevel (tcl_th_ctxt env)) names_w_ids thing_inside } + +tcExtendGhciEnv :: [TcId] -> TcM a -> TcM a +-- Used to bind Ids for GHCi identifiers bound earlier in the user interaction +-- Note especially that we bind them at TH level 'impLevel'. That's because it's +-- OK to use a variable bound earlier in the interaction in a splice, becuase +-- GHCi has already compiled it to bytecode +tcExtendGhciEnv ids thing_inside + = do { env <- getLclEnv + ; tc_extend_local_id_env env impLevel [(idName id, id) | id <- ids] thing_inside } + +tc_extend_local_id_env -- This is the guy who does the work + :: TcLclEnv + -> ThLevel + -> [(Name,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 + +tc_extend_local_id_env env th_lvl names_w_ids thing_inside + = do { traceTc (text "env2") + ; traceTc (text "env3" <+> ppr extra_env) + ; gtvs' <- tc_extend_gtvs (tcl_tyvars env) extra_global_tyvars + ; let env' = env {tcl_env = le', tcl_tyvars = gtvs', tcl_rdr = rdr_env'} + ; setLclEnv env' thing_inside } + where + extra_global_tyvars = tcTyVarsOfTypes [idType id | (_,id) <- names_w_ids] + extra_env = [ (name, ATcId { tct_id = id, + tct_level = th_lvl, + tct_type = id_ty, + tct_co = case isRefineableTy id_ty of + (True,_) -> Unrefineable + (_,True) -> Rigid idHsWrapper + _ -> Wobbly}) + | (name,id) <- names_w_ids, let id_ty = idType id] + le' = extendNameEnvList (tcl_env env) extra_env + rdr_env' = extendLocalRdrEnv (tcl_rdr env) [name | (name,_) <- names_w_ids] \end{code} @@ -416,20 +448,30 @@ find_thing _ _ thing = pprPanic "find_thing" (ppr thing) \end{code} \begin{code} -refineEnvironment :: Refinement -> TcM a -> TcM a +refineEnvironment + :: Refinement + -> Bool -- whether type equations are involved + -> TcM a + -> TcM a -- I don't think I have to refine the set of global type variables in scope -- Reason: the refinement never increases that set -refineEnvironment reft thing_inside - | isEmptyRefinement reft -- Common case +refineEnvironment reft otherEquations thing_inside + | isEmptyRefinement reft -- Common case + , not otherEquations = thing_inside | otherwise = do { env <- getLclEnv ; let le' = mapNameEnv refine (tcl_env env) ; setLclEnv (env {tcl_env = le'}) thing_inside } where - refine elt@(ATcId { tct_co = Just co, tct_type = ty }) + refine elt@(ATcId { tct_co = Rigid co, tct_type = ty }) | Just (co', ty') <- refineType reft ty - = elt { tct_co = Just (WpCo co' <.> co), tct_type = ty' } + = elt { tct_co = Rigid (WpCo co' <.> co), tct_type = ty' } + refine elt@(ATcId { tct_co = Wobbly}) +-- Main new idea: make wobbly things invisible whenever there +-- is a refinement of any sort +-- | otherEquations + = elt { tct_co = WobblyInvisible} refine (ATyVar tv ty) | Just (_, ty') <- refineType reft ty = ATyVar tv ty' -- Ignore the coercion that refineType returns @@ -628,7 +670,7 @@ 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 :: Class -> [Type] -> SrcSpan -> TcM Name newDFunName clas (ty:_) loc = do { index <- nextDFunIndex ; is_boot <- tcIsHsBoot @@ -642,12 +684,12 @@ newDFunName clas (ty:_) loc newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc) \end{code} -Make a name for the representation tycon of a data/newtype instance. It's an +Make a name for the representation tycon of a family instance. It's an *external* name, like otber top-level names, and hence must be made with newGlobalBinder. \begin{code} -newFamInstTyConName :: Name -> SrcLoc -> TcM Name +newFamInstTyConName :: Name -> SrcSpan -> TcM Name newFamInstTyConName tc_name loc = do { index <- nextDFunIndex ; mod <- getModule @@ -676,11 +718,4 @@ notFound name wrongThingErr expected thing name = failWithTc (pprTcTyThingCategory thing <+> quotes (ppr name) <+> ptext SLIT("used as a") <+> text expected) - -famInstNotFound tycon tys what - = failWithTc (msg <+> quotes (ppr tycon <+> hsep (map pprParendType tys))) - where - msg = case what of - [] -> ptext SLIT("No instance for") - xs -> ptext SLIT("More than one instance for") \end{code}