X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypes%2FType.lhs;h=872feb06f55763bbc15254171cdb7ad53898243b;hb=28a464a75e14cece5db40f2765a29348273ff2d2;hp=f2f06c8ca74e0ac3680718ce7cd98800c4281159;hpb=339d5220bcb7e8ca344ca5ec6e862d2373267be8;p=ghc-hetmet.git diff --git a/ghc/compiler/types/Type.lhs b/ghc/compiler/types/Type.lhs index f2f06c8..872feb0 100644 --- a/ghc/compiler/types/Type.lhs +++ b/ghc/compiler/types/Type.lhs @@ -23,13 +23,11 @@ module Type ( splitFunTys, splitFunTysN, funResultTy, funArgTy, zipFunTys, isFunTy, - mkGenTyConApp, mkTyConApp, mkTyConTy, + mkTyConApp, mkTyConTy, tyConAppTyCon, tyConAppArgs, splitTyConApp_maybe, splitTyConApp, - mkSynTy, - - repType, typePrimRep, coreView, deepCoreView, + repType, typePrimRep, coreView, tcView, mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys, applyTy, applyTys, isForAllTy, dropForAlls, @@ -54,6 +52,7 @@ module Type ( tidyTyVarBndr, tidyFreeTyVars, tidyOpenTyVar, tidyOpenTyVars, tidyTopType, tidyPred, + tidyKind, -- Comparison coreEqType, tcEqType, tcEqTypes, tcCmpType, tcCmpTypes, @@ -63,15 +62,15 @@ module Type ( seqType, seqTypes, -- Type substitutions - TvSubst(..), -- Representation visible to a few friends - TvSubstEnv, emptyTvSubst, - mkTvSubst, zipTvSubst, zipTopTvSubst, mkTopTvSubst, + TvSubstEnv, emptyTvSubstEnv, -- Representation widely visible + TvSubst(..), emptyTvSubst, -- Representation visible to a few friends + mkTvSubst, mkOpenTvSubst, zipOpenTvSubst, zipTopTvSubst, mkTopTvSubst, notElemTvSubst, getTvSubstEnv, setTvSubstEnv, getTvInScope, extendTvInScope, - extendTvSubst, extendTvSubstList, isInScope, + extendTvSubst, extendTvSubstList, isInScope, composeTvSubst, zipTyEnv, -- Performing substitution on types - substTy, substTys, substTyWith, substTheta, substTyVar, substTyVarBndr, - deShadowTy, + substTy, substTys, substTyWith, substTheta, + substPred, substTyVar, substTyVarBndr, deShadowTy, lookupTyVar, -- Pretty-printing pprType, pprParendType, pprTyThingCategory, @@ -87,24 +86,25 @@ import TypeRep -- friends: import Kind -import Var ( Var, TyVar, tyVarKind, tyVarName, setTyVarName ) +import Var ( Var, TyVar, tyVarKind, tyVarName, setTyVarName, mkTyVar ) import VarEnv import VarSet -import Name ( NamedThing(..), mkInternalName, tidyOccName ) +import OccName ( tidyOccName ) +import Name ( NamedThing(..), mkInternalName, tidyNameOcc ) import Class ( Class, classTyCon ) import TyCon ( TyCon, isRecursiveTyCon, isPrimTyCon, isUnboxedTupleTyCon, isUnLiftedTyCon, isFunTyCon, isNewTyCon, newTyConRep, newTyConRhs, - isAlgTyCon, isSynTyCon, tyConArity, newTyConRhs_maybe, - tyConKind, getSynTyConDefn, PrimRep(..), tyConPrimRep, + isAlgTyCon, tyConArity, + tcExpandTyCon_maybe, coreExpandTyCon_maybe, + tyConKind, PrimRep(..), tyConPrimRep, ) -- others -import CmdLineOpts ( opt_DictsStrict ) +import StaticFlags ( opt_DictsStrict ) import SrcLoc ( noSrcLoc ) -import Unique ( Uniquable(..) ) -import Util ( mapAccumL, seqList, lengthIs, snocView, thenCmp, isEqual ) +import Util ( mapAccumL, seqList, lengthIs, snocView, thenCmp, isEqual, all2 ) import Outputable import UniqSet ( sizeUniqSet ) -- Should come via VarSet import Maybe ( isJust ) @@ -126,27 +126,7 @@ coreView :: Type -> Maybe Type -- its underlying representation type. -- Returns Nothing if there is nothing to look through. -- --- By being non-recursive and inlined, this case analysis gets efficiently --- joined onto the case analysis that the caller is already doing -coreView (NoteTy _ ty) = Just ty -coreView (PredTy p) = Just (predTypeRep p) -coreView (TyConApp tc tys) = expandNewTcApp tc tys -coreView ty = Nothing - -deepCoreView :: Type -> Type --- Apply coreView recursively -deepCoreView ty - | Just ty' <- coreView ty = deepCoreView ty' -deepCoreView (TyVarTy tv) = TyVarTy tv -deepCoreView (TyConApp tc tys) = TyConApp tc (map deepCoreView tys) -deepCoreView (AppTy t1 t2) = AppTy (deepCoreView t1) (deepCoreView t2) -deepCoreView (FunTy t1 t2) = FunTy (deepCoreView t1) (deepCoreView t2) -deepCoreView (ForAllTy tv ty) = ForAllTy tv (deepCoreView ty) - -- No NoteTy, no PredTy - -expandNewTcApp :: TyCon -> [Type] -> Maybe Type --- A local helper function (not exported) --- Expands *the outermoset level of* a newtype application to +-- In the case of newtypes, it returns -- *either* a vanilla TyConApp (recursive newtype, or non-saturated) -- *or* the newtype representation (otherwise), meaning the -- type written in the RHS of the newtype decl, @@ -159,9 +139,25 @@ expandNewTcApp :: TyCon -> [Type] -> Maybe Type -- on S gives Just T -- on T gives Nothing (no expansion) -expandNewTcApp tc tys = case newTyConRhs_maybe tc tys of - Nothing -> Nothing - Just (tenv, rhs) -> Just (substTy (mkTopTvSubst tenv) rhs) +-- By being non-recursive and inlined, this case analysis gets efficiently +-- joined onto the case analysis that the caller is already doing +coreView (NoteTy _ ty) = Just ty +coreView (PredTy p) = Just (predTypeRep p) +coreView (TyConApp tc tys) | Just (tenv, rhs, tys') <- coreExpandTyCon_maybe tc tys + = Just (mkAppTys (substTy (mkTopTvSubst tenv) rhs) tys') + -- Its important to use mkAppTys, rather than (foldl AppTy), + -- because the function part might well return a + -- partially-applied type constructor; indeed, usually will! +coreView ty = Nothing + +----------------------------------------------- +{-# INLINE tcView #-} +tcView :: Type -> Maybe Type +-- Same, but for the type checker, which just looks through synonyms +tcView (NoteTy _ ty) = Just ty +tcView (TyConApp tc tys) | Just (tenv, rhs, tys') <- tcExpandTyCon_maybe tc tys + = Just (mkAppTys (substTy (mkTopTvSubst tenv) rhs) tys') +tcView ty = Nothing \end{code} @@ -209,9 +205,9 @@ mkAppTy orig_ty1 orig_ty2 = mk_app orig_ty1 where mk_app (NoteTy _ ty1) = mk_app ty1 - mk_app (TyConApp tc tys) = mkGenTyConApp tc (tys ++ [orig_ty2]) + mk_app (TyConApp tc tys) = mkTyConApp tc (tys ++ [orig_ty2]) mk_app ty1 = AppTy orig_ty1 orig_ty2 - -- We call mkGenTyConApp because the TyConApp could be an + -- Note that the TyConApp could be an -- under-saturated type synonym. GHC allows that; e.g. -- type Foo k = k a -> k a -- type Id x = x @@ -231,8 +227,8 @@ mkAppTys orig_ty1 orig_tys2 = mk_app orig_ty1 where mk_app (NoteTy _ ty1) = mk_app ty1 - mk_app (TyConApp tc tys) = mkGenTyConApp tc (tys ++ orig_tys2) - -- mkGenTyConApp: see notes with mkAppTy + mk_app (TyConApp tc tys) = mkTyConApp tc (tys ++ orig_tys2) + -- mkTyConApp: see notes with mkAppTy mk_app ty1 = foldl AppTy orig_ty1 orig_tys2 splitAppTy_maybe :: Type -> Maybe (Type, Type) @@ -327,20 +323,13 @@ funArgTy ty = pprPanic "funArgTy" (ppr ty) as apppropriate. \begin{code} -mkGenTyConApp :: TyCon -> [Type] -> Type -mkGenTyConApp tc tys - | isSynTyCon tc = mkSynTy tc tys - | otherwise = mkTyConApp tc tys - mkTyConApp :: TyCon -> [Type] -> Type --- Assumes TyCon is not a SynTyCon; use mkSynTy instead for those mkTyConApp tycon tys | isFunTyCon tycon, [ty1,ty2] <- tys = FunTy ty1 ty2 | otherwise - = ASSERT(not (isSynTyCon tycon)) - TyConApp tycon tys + = TyConApp tycon tys mkTyConTy :: TyCon -> Type mkTyConTy tycon = mkTyConApp tycon [] @@ -372,32 +361,6 @@ splitTyConApp_maybe other = Nothing SynTy ~~~~~ -\begin{code} -mkSynTy tycon tys - | n_args == arity -- Exactly saturated - = mk_syn tys - | n_args > arity -- Over-saturated - = case splitAt arity tys of { (as,bs) -> mkAppTys (mk_syn as) bs } - -- Its important to use mkAppTys, rather than (foldl AppTy), - -- because (mk_syn as) might well return a partially-applied - -- type constructor; indeed, usually will! - | otherwise -- Un-saturated - = TyConApp tycon tys - -- For the un-saturated case we build TyConApp directly - -- (mkTyConApp ASSERTs that the tc isn't a SynTyCon). - -- Here we are relying on checkValidType to find - -- the error. What we can't do is use mkSynTy with - -- too few arg tys, because that is utterly bogus. - - where - mk_syn tys = NoteTy (SynNote (TyConApp tycon tys)) - (substTyWith tyvars tys body) - - (tyvars, body) = ASSERT( isSynTyCon tycon ) getSynTyConDefn tycon - arity = tyConArity tycon - n_args = length tys -\end{code} - Notes on type synonyms ~~~~~~~~~~~~~~~~~~~~~~ The various "split" functions (splitFunTy, splitRhoTy, splitForAllTy) try @@ -426,13 +389,23 @@ It's useful in the back end. \begin{code} repType :: Type -> Type -- Only applied to types of kind *; hence tycons are saturated -repType (ForAllTy _ ty) = repType ty -repType (NoteTy _ ty) = repType ty -repType (PredTy p) = repType (predTypeRep p) -repType (TyConApp tc tys) - | isNewTyCon tc = ASSERT( tys `lengthIs` tyConArity tc ) - repType (new_type_rep tc tys) -repType ty = ty +repType ty | Just ty' <- coreView ty = repType ty' +repType (ForAllTy _ ty) = repType ty +repType (TyConApp tc tys) + | isNewTyCon tc = -- Recursive newtypes are opaque to coreView + -- but we must expand them here. Sure to + -- be saturated because repType is only applied + -- to types of kind * + ASSERT( isRecursiveTyCon tc && + tys `lengthIs` tyConArity tc ) + repType (new_type_rep tc tys) +repType ty = ty + +-- new_type_rep doesn't ask any questions: +-- it just expands newtype, whether recursive or not +new_type_rep new_tycon tys = ASSERT( tys `lengthIs` tyConArity new_tycon ) + case newTyConRep new_tycon of + (tvs, rep_ty) -> substTyWith tvs tys rep_ty -- ToDo: this could be moved to the code generator, using splitTyConApp instead -- of inspecting the type directly. @@ -449,11 +422,6 @@ typePrimRep ty = case repType ty of -- (we claim) there is no way to constrain f's kind any other -- way. --- new_type_rep doesn't ask any questions: --- it just expands newtype, whether recursive or not -new_type_rep new_tycon tys = ASSERT( tys `lengthIs` tyConArity new_tycon ) - case newTyConRep new_tycon of - (tvs, rep_ty) -> substTyWith tvs tys rep_ty \end{code} @@ -588,8 +556,9 @@ splitRecNewType_maybe (TyConApp tc tys) -- to *types* (of kind *) ASSERT( isRecursiveTyCon tc ) -- Guaranteed by coreView case newTyConRhs tc of - (tvs, rep_ty) -> Just (substTyWith tvs tys rep_ty) - + (tvs, rep_ty) -> ASSERT( length tvs == length tys ) + Just (substTyWith tvs tys rep_ty) + splitRecNewType_maybe other = Nothing \end{code} @@ -622,29 +591,14 @@ typeKind (ForAllTy tv ty) = typeKind ty ~~~~~~~~~~~~~~~~~~~~~~~~ \begin{code} tyVarsOfType :: Type -> TyVarSet +-- NB: for type synonyms tyVarsOfType does *not* expand the synonym tyVarsOfType (TyVarTy tv) = unitVarSet tv tyVarsOfType (TyConApp tycon tys) = tyVarsOfTypes tys tyVarsOfType (NoteTy (FTVNote tvs) ty2) = tvs -tyVarsOfType (NoteTy (SynNote ty1) ty2) = tyVarsOfType ty2 -- See note [Syn] below tyVarsOfType (PredTy sty) = tyVarsOfPred sty tyVarsOfType (FunTy arg res) = tyVarsOfType arg `unionVarSet` tyVarsOfType res tyVarsOfType (AppTy fun arg) = tyVarsOfType fun `unionVarSet` tyVarsOfType arg -tyVarsOfType (ForAllTy tyvar ty) = tyVarsOfType ty `minusVarSet` unitVarSet tyvar - --- Note [Syn] --- Consider --- type T a = Int --- What are the free tyvars of (T x)? Empty, of course! --- Here's the example that Ralf Laemmel showed me: --- foo :: (forall a. C u a -> C u a) -> u --- mappend :: Monoid u => u -> u -> u --- --- bar :: Monoid u => u --- bar = foo (\t -> t `mappend` t) --- We have to generalise at the arg to f, and we don't --- want to capture the constraint (Monad (C u a)) because --- it appears to mention a. Pretty silly, but it was useful to him. - +tyVarsOfType (ForAllTy tyvar ty) = delVarSet (tyVarsOfType ty) tyvar tyVarsOfTypes :: [Type] -> TyVarSet tyVarsOfTypes tys = foldr (unionVarSet.tyVarsOfType) emptyVarSet tys @@ -662,6 +616,7 @@ addFreeTyVars ty@(NoteTy (FTVNote _) _) = ty addFreeTyVars ty = NoteTy (FTVNote (tyVarsOfType ty)) ty \end{code} + %************************************************************************ %* * \subsection{TidyType} @@ -681,9 +636,7 @@ tidyTyVarBndr (tidy_env, subst) tyvar where subst' = extendVarEnv subst tyvar tyvar' tyvar' = setTyVarName tyvar name' - name' = mkInternalName (getUnique name) occ' noSrcLoc - -- Note: make a *user* tyvar, so it printes nicely - -- Could extract src loc, but no need. + name' = tidyNameOcc name occ' where name = tyVarName tyvar @@ -719,7 +672,6 @@ tidyType env@(tidy_env, subst) ty where (envp, tvp) = tidyTyVarBndr env tv - go_note (SynNote ty) = SynNote $! (go ty) go_note note@(FTVNote ftvs) = note -- No need to tidy the free tyvars tidyTypes env tys = map (tidyType env) tys @@ -748,6 +700,43 @@ tidyTopType ty = tidyType emptyTidyEnv ty \end{code} +%************************************************************************ +%* * + Tidying Kinds +%* * +%************************************************************************ + +We use a grevious hack for tidying KindVars. A TidyEnv contains +a (VarEnv Var) substitution, to express the renaming; but +KindVars are not Vars. The Right Thing ultimately is to make them +into Vars (and perhaps make Kinds into Types), but I just do a hack +here: I make up a TyVar just to remember the new OccName for the +renamed KindVar + +\begin{code} +tidyKind :: TidyEnv -> Kind -> (TidyEnv, Kind) +tidyKind env@(tidy_env, subst) (KindVar kvar) + | Just tv <- lookupVarEnv_Directly subst uniq + = (env, KindVar (setKindVarOcc kvar (getOccName tv))) + | otherwise + = ((tidy', subst'), KindVar kvar') + where + uniq = kindVarUniq kvar + (tidy', occ') = tidyOccName tidy_env (kindVarOcc kvar) + kvar' = setKindVarOcc kvar occ' + fake_tv = mkTyVar tv_name (panic "tidyKind:fake tv kind") + tv_name = mkInternalName uniq occ' noSrcLoc + subst' = extendVarEnv subst fake_tv fake_tv + +tidyKind env (FunKind k1 k2) + = (env2, FunKind k1' k2') + where + (env1, k1') = tidyKind env k1 + (env2, k2') = tidyKind env1 k2 + +tidyKind env k = (env, k) -- Atomic kinds +\end{code} + %************************************************************************ %* * @@ -836,7 +825,6 @@ seqTypes [] = () seqTypes (ty:tys) = seqType ty `seq` seqTypes tys seqNote :: TyNote -> () -seqNote (SynNote ty) = seqType ty seqNote (FTVNote set) = sizeUniqSet set `seq` () seqPred :: PredType -> () @@ -847,30 +835,58 @@ seqPred (IParam n ty) = n `seq` seqType ty %************************************************************************ %* * - Comparison of types + Equality for Core types (We don't use instances so that we know where it happens) %* * %************************************************************************ -Two flavours: +Note that eqType works right even for partial applications of newtypes. +See Note [Newtype eta] in TyCon.lhs -* tcEqType, tcCmpType do *not* look through newtypes, PredTypes -* coreEqType *does* look through them +\begin{code} +coreEqType :: Type -> Type -> Bool +coreEqType t1 t2 + = eq rn_env t1 t2 + where + rn_env = mkRnEnv2 (mkInScopeSet (tyVarsOfType t1 `unionVarSet` tyVarsOfType t2)) -Note that eqType can respond 'False' for partial applications of newtypes. -Consider - newtype Parser m a = MkParser (Foogle m a) -Does - Monad (Parser m) `eqType` Monad (Foogle m) -Well, yes, but eqType won't see that they are the same. -I don't think this is harmful, but it's soemthing to watch out for. + eq env (TyVarTy tv1) (TyVarTy tv2) = rnOccL env tv1 == rnOccR env tv2 + eq env (ForAllTy tv1 t1) (ForAllTy tv2 t2) = eq (rnBndr2 env tv1 tv2) t1 t2 + eq env (AppTy s1 t1) (AppTy s2 t2) = eq env s1 s2 && eq env t1 t2 + eq env (FunTy s1 t1) (FunTy s2 t2) = eq env s1 s2 && eq env t1 t2 + eq env (TyConApp tc1 tys1) (TyConApp tc2 tys2) + | tc1 == tc2, all2 (eq env) tys1 tys2 = True + -- The lengths should be equal because + -- the two types have the same kind + -- NB: if the type constructors differ that does not + -- necessarily mean that the types aren't equal + -- (synonyms, newtypes) + -- Even if the type constructors are the same, but the arguments + -- differ, the two types could be the same (e.g. if the arg is just + -- ignored in the RHS). In both these cases we fall through to an + -- attempt to expand one side or the other. + + -- Now deal with newtypes, synonyms, pred-tys + eq env t1 t2 | Just t1' <- coreView t1 = eq env t1' t2 + | Just t2' <- coreView t2 = eq env t1 t2' + + -- Fall through case; not equal! + eq env t1 t2 = False +\end{code} -First, the external interface -\begin{code} -coreEqType :: Type -> Type -> Bool -coreEqType t1 t2 = isEqual $ cmpType (deepCoreView t1) (deepCoreView t2) +%************************************************************************ +%* * + Comparision for source types + (We don't use instances so that we know where it happens) +%* * +%************************************************************************ +Note that + tcEqType, tcCmpType +do *not* look through newtypes, PredTypes + +\begin{code} tcEqType :: Type -> Type -> Bool tcEqType t1 t2 = isEqual $ cmpType t1 t2 @@ -912,23 +928,8 @@ cmpPred p1 p2 = cmpPredX rn_env p1 p2 rn_env = mkRnEnv2 (mkInScopeSet (tyVarsOfPred p1 `unionVarSet` tyVarsOfPred p2)) cmpTypeX :: RnEnv2 -> Type -> Type -> Ordering -- Main workhorse - --- NB: we *cannot* short-cut the newtype comparison thus: --- eqTypeX env (NewTcApp tc1 tys1) (NewTcApp tc2 tys2) --- | (tc1 == tc2) = (eqTypeXs env tys1 tys2) --- --- Consider: --- newtype T a = MkT [a] --- newtype Foo m = MkFoo (forall a. m a -> Int) --- w1 :: Foo [] --- w1 = ... --- --- w2 :: Foo T --- w2 = MkFoo (\(MkT x) -> case w1 of MkFoo f -> f x) --- --- We end up with w2 = w1; so we need that Foo T = Foo [] --- but we can only expand saturated newtypes, so just comparing --- T with [] won't do. +cmpTypeX env t1 t2 | Just t1' <- tcView t1 = cmpTypeX env t1' t2 + | Just t2' <- tcView t2 = cmpTypeX env t1 t2' cmpTypeX env (TyVarTy tv1) (TyVarTy tv2) = rnOccL env tv1 `compare` rnOccR env tv2 cmpTypeX env (ForAllTy tv1 t1) (ForAllTy tv2 t2) = cmpTypeX (rnBndr2 env tv1 tv2) t1 t2 @@ -936,7 +937,6 @@ cmpTypeX env (AppTy s1 t1) (AppTy s2 t2) = cmpTypeX env s1 s2 `thenC cmpTypeX env (FunTy s1 t1) (FunTy s2 t2) = cmpTypeX env s1 s2 `thenCmp` cmpTypeX env t1 t2 cmpTypeX env (PredTy p1) (PredTy p2) = cmpPredX env p1 p2 cmpTypeX env (TyConApp tc1 tys1) (TyConApp tc2 tys2) = (tc1 `compare` tc2) `thenCmp` cmpTypesX env tys1 tys2 -cmpTypeX env (NoteTy _ t1) t2 = cmpTypeX env t1 t2 cmpTypeX env t1 (NoteTy _ t2) = cmpTypeX env t1 t2 -- Deal with the rest: TyVarTy < AppTy < FunTy < TyConApp < ForAllTy < PredTy @@ -1025,11 +1025,30 @@ type TvSubstEnv = TyVarEnv Type -- in the middle of matching, and unification (see Types.Unify) -- So you have to look at the context to know if it's idempotent or -- apply-once or whatever +emptyTvSubstEnv :: TvSubstEnv +emptyTvSubstEnv = emptyVarEnv + +composeTvSubst :: InScopeSet -> TvSubstEnv -> TvSubstEnv -> TvSubstEnv +-- (compose env1 env2)(x) is env1(env2(x)); i.e. apply env2 then env1 +-- It assumes that both are idempotent +-- Typically, env1 is the refinement to a base substitution env2 +composeTvSubst in_scope env1 env2 + = env1 `plusVarEnv` mapVarEnv (substTy subst1) env2 + -- First apply env1 to the range of env2 + -- Then combine the two, making sure that env1 loses if + -- both bind the same variable; that's why env1 is the + -- *left* argument to plusVarEnv, because the right arg wins + where + subst1 = TvSubst in_scope env1 emptyTvSubst = TvSubst emptyInScopeSet emptyVarEnv + isEmptyTvSubst :: TvSubst -> Bool isEmptyTvSubst (TvSubst _ env) = isEmptyVarEnv env +mkTvSubst :: InScopeSet -> TvSubstEnv -> TvSubst +mkTvSubst = TvSubst + getTvSubstEnv :: TvSubst -> TvSubstEnv getTvSubstEnv (TvSubst _ env) = env @@ -1039,6 +1058,9 @@ getTvInScope (TvSubst in_scope _) = in_scope isInScope :: Var -> TvSubst -> Bool isInScope v (TvSubst in_scope _) = v `elemInScopeSet` in_scope +notElemTvSubst :: TyVar -> TvSubst -> Bool +notElemTvSubst tv (TvSubst _ env) = not (tv `elemVarEnv` env) + setTvSubstEnv :: TvSubst -> TvSubstEnv -> TvSubst setTvSubstEnv (TvSubst in_scope _) env = TvSubst in_scope env @@ -1052,16 +1074,20 @@ extendTvSubstList :: TvSubst -> [TyVar] -> [Type] -> TvSubst extendTvSubstList (TvSubst in_scope env) tvs tys = TvSubst in_scope (extendVarEnvList env (tvs `zip` tys)) --- mkTvSubst and zipTvSubst generate the in-scope set from +-- mkOpenTvSubst and zipOpenTvSubst generate the in-scope set from -- the types given; but it's just a thunk so with a bit of luck -- it'll never be evaluated -mkTvSubst :: TvSubstEnv -> TvSubst -mkTvSubst env - = TvSubst (mkInScopeSet (tyVarsOfTypes (varEnvElts env))) env +mkOpenTvSubst :: TvSubstEnv -> TvSubst +mkOpenTvSubst env = TvSubst (mkInScopeSet (tyVarsOfTypes (varEnvElts env))) env -zipTvSubst :: [TyVar] -> [Type] -> TvSubst -zipTvSubst tyvars tys +zipOpenTvSubst :: [TyVar] -> [Type] -> TvSubst +zipOpenTvSubst tyvars tys +#ifdef DEBUG + | length tyvars /= length tys + = pprTrace "zipOpenTvSubst" (ppr tyvars $$ ppr tys) emptyTvSubst + | otherwise +#endif = TvSubst (mkInScopeSet (tyVarsOfTypes tys)) (zipTyEnv tyvars tys) -- mkTopTvSubst is called when doing top-level substitutions. @@ -1071,7 +1097,13 @@ mkTopTvSubst :: [(TyVar, Type)] -> TvSubst mkTopTvSubst prs = TvSubst emptyInScopeSet (mkVarEnv prs) zipTopTvSubst :: [TyVar] -> [Type] -> TvSubst -zipTopTvSubst tyvars tys = TvSubst emptyInScopeSet (zipTyEnv tyvars tys) +zipTopTvSubst tyvars tys +#ifdef DEBUG + | length tyvars /= length tys + = pprTrace "zipOpenTvSubst" (ppr tyvars $$ ppr tys) emptyTvSubst + | otherwise +#endif + = TvSubst emptyInScopeSet (zipTyEnv tyvars tys) zipTyEnv :: [TyVar] -> [Type] -> TvSubstEnv zipTyEnv tyvars tys @@ -1098,6 +1130,8 @@ zip_ty_env (tv:tvs) (ty:tys) env = zip_ty_env tvs tys (extendVarEnv env tv ty) -- and so generated a rep type mentioning t not t2. -- -- Simplest fix is to nuke the "optimisation" +zip_ty_env tvs tys env = pprTrace "Var/Type length mismatch: " (ppr tvs $$ ppr tys) env +-- zip_ty_env _ _ env = env instance Outputable TvSubst where ppr (TvSubst ins env) @@ -1114,7 +1148,8 @@ instance Outputable TvSubst where \begin{code} substTyWith :: [TyVar] -> [Type] -> Type -> Type -substTyWith tvs tys = substTy (zipTvSubst tvs tys) +substTyWith tvs tys = ASSERT( length tvs == length tys ) + substTy (zipOpenTvSubst tvs tys) substTy :: TvSubst -> Type -> Type substTy subst ty | isEmptyTvSubst subst = ty @@ -1124,9 +1159,6 @@ substTys :: TvSubst -> [Type] -> [Type] substTys subst tys | isEmptyTvSubst subst = tys | otherwise = map (subst_ty subst) tys -deShadowTy :: Type -> Type -- Remove any shadowing from the type -deShadowTy ty = subst_ty emptyTvSubst ty - substTheta :: TvSubst -> ThetaType -> ThetaType substTheta subst theta | isEmptyTvSubst subst = theta @@ -1136,6 +1168,12 @@ substPred :: TvSubst -> PredType -> PredType substPred subst (IParam n ty) = IParam n (subst_ty subst ty) substPred subst (ClassP clas tys) = ClassP clas (map (subst_ty subst) tys) +deShadowTy :: TyVarSet -> Type -> Type -- Remove any nested binders mentioning tvs +deShadowTy tvs ty + = subst_ty (mkTvSubst in_scope emptyTvSubstEnv) ty + where + in_scope = mkInScopeSet tvs + -- Note that the in_scope set is poked only if we hit a forall -- so it may often never be fully computed subst_ty subst ty @@ -1147,7 +1185,6 @@ subst_ty subst ty go (PredTy p) = PredTy $! (substPred subst p) - go (NoteTy (SynNote ty1) ty2) = NoteTy (SynNote $! (go ty1)) $! (go ty2) go (NoteTy (FTVNote _) ty2) = go ty2 -- Discard the free tyvar note go (FunTy arg res) = (FunTy $! (go arg)) $! (go res) @@ -1159,11 +1196,14 @@ subst_ty subst ty (subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty) substTyVar :: TvSubst -> TyVar -> Type -substTyVar (TvSubst in_scope env) tv - = case (lookupVarEnv env tv) of +substTyVar subst tv + = case lookupTyVar subst tv of Nothing -> TyVarTy tv Just ty' -> ty' -- See Note [Apply Once] +lookupTyVar :: TvSubst -> TyVar -> Maybe Type +lookupTyVar (TvSubst in_scope env) tv = lookupVarEnv env tv + substTyVarBndr :: TvSubst -> TyVar -> (TvSubst, TyVar) substTyVarBndr subst@(TvSubst in_scope env) old_var | old_var == new_var -- No need to clone @@ -1190,5 +1230,3 @@ substTyVarBndr subst@(TvSubst in_scope env) old_var new_var = uniqAway in_scope old_var -- The uniqAway part makes sure the new variable is not already in scope \end{code} - -