tcLookupLocatedGlobal, tcLookupGlobal,
tcLookupField, tcLookupTyCon, tcLookupClass, tcLookupDataCon,
tcLookupLocatedGlobalId, tcLookupLocatedTyCon,
- tcLookupLocatedClass,
+ tcLookupLocatedClass, tcLookupFamInst,
-- Local environment
tcExtendKindEnv, tcExtendKindEnvTvs,
import VarEnv
import RdrName
import InstEnv
+import FamInstEnv
import DataCon
import TyCon
import Class
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}
%************************************************************************
-- 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}
%************************************************************************
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}