; subst <- getTvSubst
; let in_scope = getTvInScope subst
subst_env = getTvSubstEnv subst
- ; case coreRefineTys in_scope con tvs scrut_ty of {
+ ; case coreRefineTys con tvs scrut_ty of {
Nothing -> return () ; -- Alternative is dead code
Just (refine, _) -> updateTvSubstEnv (composeTvSubst in_scope refine subst_env) $
do { addLoc (CasePat alt) $ do
import IdInfo ( setArityInfo, vanillaIdInfo,
newStrictnessInfo, setAllStrictnessInfo,
newDemandInfo, setNewDemandInfo )
-import Type ( Type, tidyType, tidyTyVarBndr, substTy, mkTvSubst )
+import Type ( Type, tidyType, tidyTyVarBndr, substTy, mkOpenTvSubst )
import Var ( Var, TyVar, varName )
import VarEnv
import UniqFM ( lookupUFM )
refineTidyEnv :: TidyEnv -> DataCon -> [TyVar] -> Type -> TidyEnv
-- Refine the TidyEnv in the light of the type refinement from coreRefineTys
refineTidyEnv tidy_env@(occ_env, var_env) con tvs scrut_ty
- = case coreRefineTys in_scope con tvs scrut_ty of
+ = case coreRefineTys con tvs scrut_ty of
Nothing -> tidy_env
Just (tv_subst, all_bound_here)
| all_bound_here -- Local type refinement only
-- And that means that exprType will work right everywhere
-> (occ_env, mapVarEnv (refine subst) var_env)
where
- subst = mkTvSubst in_scope tv_subst
+ subst = mkOpenTvSubst tv_subst
where
refine subst var | isId var = setIdType var (substTy subst (idType var))
| otherwise = var
- in_scope = mkInScopeSet var_env -- Seldom used
-
------------ Notes --------------
tidyNote env (Coerce t1 t2) = Coerce (tidyType env t1) (tidyType env t2)
tidyNote env note = note
lookupIfaceTop, lookupIfaceExt,
lookupOrig, lookupIfaceTc,
newIfaceName, newIfaceNames,
- extendIfaceIdEnv, extendIfaceTyVarEnv,
+ extendIfaceIdEnv, extendIfaceTyVarEnv, refineIfaceIdEnv,
tcIfaceLclId, tcIfaceTyVar,
lookupAvail, ifaceExportNames,
import TysWiredIn ( tupleTyCon, tupleCon )
import HscTypes ( NameCache(..), HscEnv(..), GenAvailInfo(..),
IfaceExport, OrigNameCache )
+import Type ( mkOpenTvSubst, substTy )
import TyCon ( TyCon, tyConName )
+import Unify ( TypeRefinement )
import DataCon ( dataConWorkId, dataConName )
-import Var ( TyVar, Id, varName )
+import Var ( TyVar, Id, varName, setIdType, idType )
import Name ( Name, nameUnique, nameModule,
nameOccName, nameSrcLoc,
getOccName, nameParent_maybe,
isWiredInName, mkIPName,
mkExternalName, mkInternalName )
import NameSet ( NameSet, emptyNameSet, addListToNameSet )
-import OccName ( OccName, isTupleOcc_maybe, tcName, dataName,
+import OccName ( OccName, isTupleOcc_maybe, tcName, dataName, mapOccEnv,
lookupOccEnv, unitOccEnv, extendOccEnv, extendOccEnvList )
import PrelNames ( gHC_PRIM, pREL_TUP )
import Module ( Module, emptyModuleEnv,
`orElse`
pprPanic "tcIfaceLclId" (ppr occ)) }
+refineIfaceIdEnv :: TypeRefinement -> IfL a -> IfL a
+refineIfaceIdEnv (tv_subst, _) thing_inside
+ = do { env <- getLclEnv
+ ; let { id_env' = mapOccEnv refine_id (if_id_env env)
+ ; refine_id id = setIdType id (substTy subst (idType id))
+ ; subst = mkOpenTvSubst tv_subst }
+ ; setLclEnv (env { if_id_env = id_env' }) thing_inside }
+
extendIfaceIdEnv :: [Id] -> IfL a -> IfL a
extendIfaceIdEnv ids thing_inside
= do { env <- getLclEnv
loadDecls, findAndReadIface )
import IfaceEnv ( lookupIfaceTop, lookupIfaceExt, newGlobalBinder,
extendIfaceIdEnv, extendIfaceTyVarEnv, newIPName,
- tcIfaceTyVar, tcIfaceLclId, lookupIfaceTc,
+ tcIfaceTyVar, tcIfaceLclId, lookupIfaceTc, refineIfaceIdEnv,
newIfaceName, newIfaceNames, ifaceExportNames )
import BuildTyCl ( buildSynTyCon, buildAlgTyCon, buildDataCon, buildClass,
mkAbstractTyConRhs, mkDataTyConRhs, mkNewTyConRhs )
ModIface(..), ModDetails(..), HomeModInfo(..),
emptyModDetails, lookupTypeEnv, lookupType, typeEnvIds )
import InstEnv ( Instance(..), mkImportedInstance )
+import Unify ( coreRefineTys )
import CoreSyn
import CoreUtils ( exprType )
import CoreUnfold
ppr (con, arg_names, rhs) $$ ppr tyvars $$ ppr arg_tys )
zipWith mkLocalId id_names arg_tys
+ Just refine = coreRefineTys con tyvars (mkTyConApp tycon inst_tys)
+
; rhs' <- extendIfaceTyVarEnv tyvars $
extendIfaceIdEnv arg_ids $
+ refineIfaceIdEnv refine $
+ -- You might think that we don't need to refine the envt here,
+ -- but we do: \(x::a) -> case y of
+ -- MkT -> case x of { True -> ... }
+ -- In the "case x" we need to know x's type, because we use that
+ -- to find which module to look for "True" in. Sigh.
tcIfaceExpr rhs
; return (DataAlt con, tyvars ++ arg_ids, rhs') }}
(tvs,ids) = span isTyVar vs
in
simplBinders env tvs `thenSmpl` \ (env1, tvs') ->
- case coreRefineTys (getInScope env1) con tvs' (idType case_bndr') of {
+ case coreRefineTys con tvs' (idType case_bndr') of {
Nothing -- Inaccessible
| opt_PprStyle_Debug -- Hack: if debugging is on, generate an error case
-- so we can see it
import Kind ( isSubKind )
import Type ( typeKind, tyVarsOfType, tyVarsOfTypes, tyVarsOfTheta, mkTyVarTys,
TvSubstEnv, emptyTvSubstEnv, TvSubst(..), substTy, tcEqTypeX,
- tcView )
+ mkOpenTvSubst, tcView )
import TypeRep ( Type(..), PredType(..), funTyCon )
import DataCon ( DataCon, dataConInstResTy )
import Util ( snocView )
tvs2 = tyVarsOfTypes tys2
----------------------------
-coreRefineTys :: InScopeSet -- Superset of free vars of either type
- -> DataCon -> [TyVar] -- Case pattern (con tv1 .. tvn ...)
+coreRefineTys :: DataCon -> [TyVar] -- Case pattern (con tv1 .. tvn ...)
-> Type -- Type of scrutinee
-> Maybe TypeRefinement
-- for already-in-scope type variables
-- Used by Core Lint and the simplifier.
-coreRefineTys in_scope con tvs scrut_ty
+coreRefineTys con tvs scrut_ty
= maybeErrToMaybe $ initUM (tryToBind tv_set) $
do { -- Run the unifier, starting with an empty env
; subst_env <- unify emptyTvSubstEnv pat_res_ty scrut_ty
-- Find the fixed point of the resulting non-idempotent substitution
- ; let subst = TvSubst in_scope subst_env_fixpt
+ ; let subst = mkOpenTvSubst subst_env_fixpt
subst_env_fixpt = mapVarEnv (substTy subst) subst_env
; return (subst_env_fixpt, all_bound_here subst_env) }