%
\begin{code}
+{-# OPTIONS_GHC -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+-- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings
+-- for details
+
module TcEnv(
TyThing(..), TcTyThing(..), TcId,
-- Local environment
tcExtendKindEnv, tcExtendKindEnvTvs,
tcExtendTyVarEnv, tcExtendTyVarEnv2,
+ tcExtendGhciEnv,
tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2,
tcLookup, tcLookupLocated, tcLookupLocalIds,
tcLookupId, tcLookupTyVar, getScopedTyVarBinds,
topIdLvl,
-- New Ids
- newLocalName, newDFunName, newFamInstTyConName
+ newLocalName, newDFunName, newFamInstTyConName,
) where
#include "HsVersions.h"
import TcMType
import TcType
import TcGadt
+-- import TcSuspension
import qualified Type
-import Id
import Var
import VarSet
import VarEnv
import FamInstEnv
import DataCon
import TyCon
+import TypeRep
+import Coercion
import Class
import Name
import PrelNames
import HscTypes
import SrcLoc
import Outputable
+import Maybes
\end{code}
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)] | 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
+ [(fam_inst, rep_tys)] -> return $ Just (famInstTyCon fam_inst,
+ rep_tys)
+ other -> return Nothing
}
\end{code}
\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
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}
\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
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
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
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}