X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcEnv.lhs;h=e1b9bd31b70c912cf74f7b61754aa43d89c77fb6;hp=7828394b7b2d7e9faf85f6f5d2a0130bc1aabc52;hb=84923cc7de2a93c22a2f72daf9ac863959efae13;hpb=0cb269be72ffe42498c74d5be845eb27d8818423 diff --git a/compiler/typecheck/TcEnv.lhs b/compiler/typecheck/TcEnv.lhs index 7828394..e1b9bd3 100644 --- a/compiler/typecheck/TcEnv.lhs +++ b/compiler/typecheck/TcEnv.lhs @@ -1,3 +1,7 @@ +% +% (c) The University of Glasgow 2006 +% + \begin{code} module TcEnv( TyThing(..), TcTyThing(..), TcId, @@ -13,7 +17,7 @@ module TcEnv( tcLookupLocatedGlobal, tcLookupGlobal, tcLookupField, tcLookupTyCon, tcLookupClass, tcLookupDataCon, tcLookupLocatedGlobalId, tcLookupLocatedTyCon, - tcLookupLocatedClass, + tcLookupLocatedClass, tcLookupFamInst, -- Local environment tcExtendKindEnv, tcExtendKindEnvTvs, @@ -43,37 +47,30 @@ module TcEnv( #include "HsVersions.h" -import HsSyn ( LRuleDecl, LHsBinds, LSig, - LHsTyVarBndr, HsTyVarBndr(..), pprLHsBinds, - idCoercion, (<.>) ) -import TcIface ( tcImportDecl ) -import IfaceEnv ( newGlobalBinder ) +import HsSyn +import TcIface +import IfaceEnv import TcRnMonad -import TcMType ( zonkTcType, zonkTcTyVarsAndFV ) -import TcType ( Type, TcKind, TcTyVar, TcTyVarSet, TcType, - substTy, tyVarsOfType, tcTyVarsOfTypes, mkTyConApp, - getDFunTyKey, tcTyConAppTyCon, tcGetTyVar, mkTyVarTy, - tidyOpenType, isRefineableTy - ) -import TcGadt ( Refinement, refineType ) -import qualified Type ( getTyVar_maybe ) -import Id ( idName, isLocalId ) -import Var ( TyVar, Id, idType, tyVarName ) +import TcMType +import TcType +import TcGadt +import qualified Type +import Id +import Var 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, nameModule, - nameOccName ) -import PrelNames ( thFAKE ) +import RdrName +import InstEnv +import FamInstEnv +import DataCon +import TyCon +import Class +import Name +import PrelNames import NameEnv -import OccName ( mkDFunOcc, occNameString, mkInstTyTcOcc ) -import HscTypes ( extendTypeEnvList, lookupType, TyThing(..), - ExternalPackageState(..) ) -import SrcLoc ( SrcLoc, Located(..) ) +import OccName +import HscTypes +import SrcLoc import Outputable \end{code} @@ -114,13 +111,15 @@ tcLookupGlobal name Nothing -> do -- Should it have been in the local envt? - { let mod = nameModule name - ; if mod == tcg_mod env || mod == thFAKE then - notFound name -- It should be local, so panic - -- The thFAKE possibility is because it - -- might be in a declaration bracket - else - tcImportDecl name -- Go find it in an interface + { case nameModule_maybe name of + Nothing -> notFound name -- Internal names can happen in GHCi + + Just mod | mod == tcg_mod env -- Names from this module + -> notFound name -- should be in tcg_type_env + | mod == thFAKE -- Names bound in TH declaration brackets + -> notFound name -- should be in tcg_env + | otherwise + -> tcImportDecl name -- Go find it in an interface }}}}} tcLookupField :: Name -> TcM Id -- Returns the selector Id @@ -159,6 +158,25 @@ 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]) +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 + [(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 + } \end{code} %************************************************************************ @@ -326,7 +344,7 @@ tcExtendIdEnv2 names_w_ids thing_inside tct_level = th_lvl, tct_type = id_ty, tct_co = if isRefineableTy id_ty - then Just idCoercion + then Just idHsWrapper else Nothing }) | (name,id) <- names_w_ids, let id_ty = idType id] le' = extendNameEnvList (tcl_env env) extra_env @@ -362,7 +380,7 @@ findGlobals tvs tidy_env Just d -> go tidy_env1 (d:acc) things Nothing -> go tidy_env1 acc things - ignore_it ty = not (tvs `intersectsVarSet` tyVarsOfType ty) + ignore_it ty = tvs `disjointVarSet` tyVarsOfType ty ----------------------- find_thing ignore_it tidy_env (ATcId { tct_id = id }) @@ -402,16 +420,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} %************************************************************************ @@ -567,20 +590,26 @@ data InstBindings [LSig Name] -- User pragmas recorded for generating -- specialised instances - | NewTypeDerived - TyCon -- tycon for the newtype - -- Used for deriving instances of newtypes, where the - [Type] -- witness dictionary is identical to the argument - -- dictionary. Hence no bindings, no pragmas - -- The [Type] are the representation types - -- See notes in TcDeriv + | NewTypeDerived -- Used for deriving instances of newtypes, where the + -- witness dictionary is identical to the argument + -- dictionary. Hence no bindings, no pragmas. + (Maybe [PredType]) + -- Nothing => The newtype-derived instance involves type variables, + -- and the dfun has a type like df :: forall a. Eq a => Eq (T a) + -- Just (r:scs) => The newtype-defined instance has no type variables + -- so the dfun is just a constant, df :: Eq T + -- In this case we need to know waht the rep dict, r, and the + -- superclasses, scs, are. (In the Nothing case these are in the + -- dict fun's type.) + -- Invariant: these PredTypes have no free variables + -- NB: In both cases, the representation dict is the *first* dict. pprInstInfo info = vcat [ptext SLIT("InstInfo:") <+> ppr (idType (iDFunId info))] pprInstInfoDetails info = pprInstInfo info $$ nest 2 (details (iBinds info)) where details (VanillaInst b _) = pprLHsBinds b - details (NewTypeDerived _ _) = text "Derived from the representation type" + details (NewTypeDerived _) = text "Derived from the representation type" simpleInstInfoClsTy :: InstInfo -> (Class, Type) simpleInstInfoClsTy info = case instanceHead (iSpec info) of @@ -608,7 +637,7 @@ newDFunName clas (ty:_) loc occNameString (getDFunTyKey ty) dfun_occ = mkDFunOcc info_string is_boot index - ; newGlobalBinder mod dfun_occ Nothing loc } + ; newGlobalBinder mod dfun_occ loc } newDFunName clas [] loc = pprPanic "newDFunName" (ppr clas <+> ppr loc) \end{code} @@ -623,7 +652,7 @@ newFamInstTyConName tc_name loc = do { index <- nextDFunIndex ; mod <- getModule ; let occ = nameOccName tc_name - ; newGlobalBinder mod (mkInstTyTcOcc index occ) Nothing loc } + ; newGlobalBinder mod (mkInstTyTcOcc index occ) loc } \end{code} @@ -647,4 +676,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 (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}