X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=compiler%2Ftypecheck%2FTcEnv.lhs;h=0f9bf231c8c66b3c2475e73630a82bb4a5657533;hb=289ee3d0daa95445ead578f2b674987a4187993d;hp=c638c04d5e060aef26355946d6870a255c03eb6d;hpb=49c98d143c382a1341e1046f5ca00819a25691ba;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcEnv.lhs b/compiler/typecheck/TcEnv.lhs index c638c04..0f9bf23 100644 --- a/compiler/typecheck/TcEnv.lhs +++ b/compiler/typecheck/TcEnv.lhs @@ -17,7 +17,7 @@ module TcEnv( tcLookupLocatedGlobal, tcLookupGlobal, tcLookupField, tcLookupTyCon, tcLookupClass, tcLookupDataCon, tcLookupLocatedGlobalId, tcLookupLocatedTyCon, - tcLookupLocatedClass, + tcLookupLocatedClass, tcLookupFamInst, -- Local environment tcExtendKindEnv, tcExtendKindEnvTvs, @@ -42,7 +42,10 @@ module TcEnv( topIdLvl, -- New Ids - newLocalName, newDFunName, newFamInstTyConName + newLocalName, newDFunName, newFamInstTyConName, + + -- Errors + famInstNotFound ) where #include "HsVersions.h" @@ -55,12 +58,12 @@ import TcMType import TcType import TcGadt import qualified Type -import Id import Var import VarSet import VarEnv import RdrName import InstEnv +import FamInstEnv import DataCon import TyCon import Class @@ -157,6 +160,35 @@ tcLookupLocatedClass = addLocM tcLookupClass tcLookupLocatedTyCon :: Located Name -> TcM TyCon tcLookupLocatedTyCon = addLocM tcLookupTyCon + +-- Look up the representation 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 (TyCon, [Type]) +tcLookupFamInst tycon tys + | not (isOpenTyCon tycon) + = return (tycon, tys) + | otherwise + = do { env <- getGblEnv + ; eps <- getEps + ; let instEnv = (eps_fam_inst_env eps, tcg_fam_inst_env env) + ; case lookupFamInstEnv instEnv tycon tys of + [(fam_inst, rep_tys)] -> return (famInstTyCon fam_inst, rep_tys) + other -> famInstNotFound tycon tys other + } \end{code} %************************************************************************ @@ -400,16 +432,21 @@ refineEnvironment :: Refinement -> 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 + = 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 }) - = let (co', ty') = refineType reft ty - in elt { tct_co = Just (co' <.> co), tct_type = ty' } - refine (ATyVar tv ty) = ATyVar tv (snd (refineType reft ty)) - -- Ignore the coercion that refineType returns - refine elt = elt + | Just (co', ty') <- refineType reft ty + = elt { tct_co = Just (WpCo co' <.> co), tct_type = ty' } + refine (ATyVar tv ty) + | Just (_, ty') <- refineType reft ty + = ATyVar tv ty' -- Ignore the coercion that refineType returns + + refine elt = elt -- Common case \end{code} %************************************************************************ @@ -603,7 +640,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 @@ -617,12 +654,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 @@ -651,4 +688,11 @@ 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 (pprTypeApp (ppr tycon) tys)) + where + msg = ptext $ if length what > 1 + then SLIT("More than one family instance for") + else SLIT("No family instance exactly matching") \end{code}