+%
+% (c) The University of Glasgow 2006
+%
+
\begin{code}
module TcEnv(
TyThing(..), TcTyThing(..), TcId,
tcLookupLocatedGlobal, tcLookupGlobal,
tcLookupField, tcLookupTyCon, tcLookupClass, tcLookupDataCon,
tcLookupLocatedGlobalId, tcLookupLocatedTyCon,
- tcLookupLocatedClass,
+ tcLookupLocatedClass, tcLookupFamInst,
-- Local environment
tcExtendKindEnv, tcExtendKindEnvTvs,
topIdLvl,
-- New Ids
- newLocalName, newDFunName
+ newLocalName, newDFunName, newFamInstTyConName
) where
#include "HsVersions.h"
-import HsSyn ( LRuleDecl, LHsBinds, LSig,
- LHsTyVarBndr, HsTyVarBndr(..), pprLHsBinds,
- ExprCoFn(..), 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, TvSubst,
- substTy, substTyVar, tyVarsOfType, tcTyVarsOfTypes, mkTyConApp,
- getDFunTyKey, tcTyConAppTyCon, tcGetTyVar, mkTyVarTy,
- tidyOpenType, isRefineableTy
- )
-import TcGadt ( Refinement, refineType )
-import qualified Type ( getTyVar_maybe )
-import Id ( idName, isLocalId, setIdType )
-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 )
-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 )
-import HscTypes ( extendTypeEnvList, lookupType, TyThing(..), ExternalPackageState(..) )
-import SrcLoc ( SrcLoc, Located(..) )
+import OccName
+import HscTypes
+import SrcLoc
import Outputable
\end{code}
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
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)] | variable_only_subst ->
+ 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
+ subst_domain = varEnvElts . getTvSubstEnv $ subst
+ tvs = map (Type.getTyVar "tcLookupFamInst")
+ subst_domain
+ variable_only_subst = all Type.isTyVarTy subst_domain &&
+ sizeVarSet (mkVarSet tvs) == length tvs
+ -- renaming may have no repetitions
+
+ other -> famInstNotFound tycon tys other
+ }
\end{code}
%************************************************************************
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
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 })
-- 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}
%************************************************************************
[LSig Name] -- User pragmas recorded for generating
-- specialised instances
- | NewTypeDerived
- (Maybe TyCon) -- maybe a coercion 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
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}
+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 tc_name loc
+ = do { index <- nextDFunIndex
+ ; mod <- getModule
+ ; let occ = nameOccName tc_name
+ ; newGlobalBinder mod (mkInstTyTcOcc index occ) loc }
+\end{code}
+
%************************************************************************
%* *
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}