X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypes%2FType.lhs;h=872feb06f55763bbc15254171cdb7ad53898243b;hb=28a464a75e14cece5db40f2765a29348273ff2d2;hp=333b589403c4e9a65ddccc3d6a6ef59d6dc49cf0;hpb=98688c6e8fd33f31c51218cf93cbf03fe3a5e73d;p=ghc-hetmet.git diff --git a/ghc/compiler/types/Type.lhs b/ghc/compiler/types/Type.lhs index 333b589..872feb0 100644 --- a/ghc/compiler/types/Type.lhs +++ b/ghc/compiler/types/Type.lhs @@ -5,43 +5,35 @@ \begin{code} module Type ( - -- re-exports from TypeRep: - TyThing(..), - Type, PredType(..), ThetaType, - Kind, TyVarSubst, - - superKind, superBoxity, -- KX and BX respectively - liftedBoxity, unliftedBoxity, -- :: BX - openKindCon, -- :: KX - typeCon, -- :: BX -> KX - liftedTypeKind, unliftedTypeKind, openTypeKind, -- :: KX - mkArrowKind, mkArrowKinds, -- :: KX -> KX -> KX - isTypeKind, isAnyTypeKind, + -- re-exports from TypeRep + TyThing(..), Type, PredType(..), ThetaType, funTyCon, - -- exports from this module: - hasMoreBoxityInfo, defaultKind, + -- Re-exports from Kind + module Kind, + + -- Re-exports from TyCon + PrimRep(..), mkTyVarTy, mkTyVarTys, getTyVar, getTyVar_maybe, isTyVarTy, mkAppTy, mkAppTys, splitAppTy, splitAppTys, splitAppTy_maybe, - mkFunTy, mkFunTys, splitFunTy, splitFunTy_maybe, splitFunTys, + mkFunTy, mkFunTys, splitFunTy, splitFunTy_maybe, + splitFunTys, splitFunTysN, funResultTy, funArgTy, zipFunTys, isFunTy, - mkGenTyConApp, mkTyConApp, mkTyConTy, + mkTyConApp, mkTyConTy, tyConAppTyCon, tyConAppArgs, splitTyConApp_maybe, splitTyConApp, - mkSynTy, - - repType, typePrimRep, + repType, typePrimRep, coreView, tcView, mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys, applyTy, applyTys, isForAllTy, dropForAlls, -- Source types - isPredTy, predTypeRep, mkPredTy, mkPredTys, + predTypeRep, mkPredTy, mkPredTys, -- Newtypes splitRecNewType_maybe, @@ -60,13 +52,29 @@ module Type ( tidyTyVarBndr, tidyFreeTyVars, tidyOpenTyVar, tidyOpenTyVars, tidyTopType, tidyPred, + tidyKind, -- Comparison - eqType, eqKind, + coreEqType, tcEqType, tcEqTypes, tcCmpType, tcCmpTypes, + tcEqPred, tcCmpPred, tcEqTypeX, -- Seq - seqType, seqTypes - + seqType, seqTypes, + + -- Type substitutions + 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, composeTvSubst, zipTyEnv, + + -- Performing substitution on types + substTy, substTys, substTyWith, substTheta, + substPred, substTyVar, substTyVarBndr, deShadowTy, lookupTyVar, + + -- Pretty-printing + pprType, pprParendType, pprTyThingCategory, + pprPred, pprTheta, pprThetaArrow, pprClassPred ) where #include "HsVersions.h" @@ -76,31 +84,27 @@ module Type ( import TypeRep --- Other imports: - -import {-# SOURCE #-} Subst ( substTyWith ) - -- friends: -import Var ( TyVar, tyVarKind, tyVarName, setTyVarName ) +import Kind +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, - isAlgTyCon, isSynTyCon, tyConArity, - tyConKind, getSynTyConDefn, - tyConPrimRep, + isFunTyCon, isNewTyCon, newTyConRep, newTyConRhs, + isAlgTyCon, tyConArity, + tcExpandTyCon_maybe, coreExpandTyCon_maybe, + tyConKind, PrimRep(..), tyConPrimRep, ) -- others -import CmdLineOpts ( opt_DictsStrict ) +import StaticFlags ( opt_DictsStrict ) import SrcLoc ( noSrcLoc ) -import PrimRep ( PrimRep(..) ) -import Unique ( Uniquable(..) ) -import Util ( mapAccumL, seqList, lengthIs, snocView ) +import Util ( mapAccumL, seqList, lengthIs, snocView, thenCmp, isEqual, all2 ) import Outputable import UniqSet ( sizeUniqSet ) -- Should come via VarSet import Maybe ( isJust ) @@ -109,33 +113,51 @@ import Maybe ( isJust ) %************************************************************************ %* * -\subsection{Stuff to do with kinds.} + Type representation %* * %************************************************************************ +In Core, we "look through" non-recursive newtypes and PredTypes. + \begin{code} -hasMoreBoxityInfo :: Kind -> Kind -> Bool --- (k1 `hasMoreBoxityInfo` k2) checks that k1 <: k2 -hasMoreBoxityInfo k1 k2 - | k2 `eqKind` openTypeKind = isAnyTypeKind k1 - | otherwise = k1 `eqKind` k2 - -isAnyTypeKind :: Kind -> Bool --- True of kind * and *# and ? -isAnyTypeKind (TyConApp tc _) = tc == typeCon || tc == openKindCon -isAnyTypeKind (NoteTy _ k) = isAnyTypeKind k -isAnyTypeKind other = False - -isTypeKind :: Kind -> Bool --- True of kind * and *# -isTypeKind (TyConApp tc _) = tc == typeCon -isTypeKind (NoteTy _ k) = isTypeKind k -isTypeKind other = False - -defaultKind :: Kind -> Kind --- Used when generalising: default kind '?' to '*' -defaultKind kind | kind `eqKind` openTypeKind = liftedTypeKind - | otherwise = kind +{-# INLINE coreView #-} +coreView :: Type -> Maybe Type +-- Srips off the *top layer only* of a type to give +-- its underlying representation type. +-- Returns Nothing if there is nothing to look through. +-- +-- 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, +-- which may itself be a newtype +-- +-- Example: newtype R = MkR S +-- newtype S = MkS T +-- newtype T = MkT (T -> T) +-- expandNewTcApp on R gives Just S +-- on S gives Just T +-- on T gives Nothing (no expansion) + +-- 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} @@ -165,11 +187,9 @@ isTyVarTy :: Type -> Bool isTyVarTy ty = isJust (getTyVar_maybe ty) getTyVar_maybe :: Type -> Maybe TyVar -getTyVar_maybe (TyVarTy tv) = Just tv -getTyVar_maybe (NoteTy _ t) = getTyVar_maybe t -getTyVar_maybe (PredTy p) = getTyVar_maybe (predTypeRep p) -getTyVar_maybe (NewTcApp tc tys) = getTyVar_maybe (newTypeRep tc tys) -getTyVar_maybe other = Nothing +getTyVar_maybe ty | Just ty' <- coreView ty = getTyVar_maybe ty' +getTyVar_maybe (TyVarTy tv) = Just tv +getTyVar_maybe other = Nothing \end{code} @@ -182,14 +202,12 @@ invariant: use it. \begin{code} mkAppTy orig_ty1 orig_ty2 - = ASSERT2( not (isPredTy orig_ty1), crudePprType orig_ty1 ) -- Source types are of kind * - mk_app orig_ty1 + = mk_app orig_ty1 where mk_app (NoteTy _ ty1) = mk_app ty1 - mk_app (NewTcApp tc tys) = NewTcApp tc (tys ++ [orig_ty2]) - 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 @@ -206,26 +224,20 @@ mkAppTys orig_ty1 [] = orig_ty1 -- returns to (Ratio Integer), which has needlessly lost -- the Rational part. mkAppTys orig_ty1 orig_tys2 - = ASSERT( not (isPredTy orig_ty1) ) -- Source types are of kind * - mk_app orig_ty1 + = mk_app orig_ty1 where mk_app (NoteTy _ ty1) = mk_app ty1 - mk_app (NewTcApp tc tys) = NewTcApp tc (tys ++ orig_tys2) mk_app (TyConApp tc tys) = mkTyConApp tc (tys ++ orig_tys2) - -- Use mkTyConApp in case tc is (->) + -- mkTyConApp: see notes with mkAppTy mk_app ty1 = foldl AppTy orig_ty1 orig_tys2 splitAppTy_maybe :: Type -> Maybe (Type, Type) +splitAppTy_maybe ty | Just ty' <- coreView ty = splitAppTy_maybe ty' splitAppTy_maybe (FunTy ty1 ty2) = Just (TyConApp funTyCon [ty1], ty2) splitAppTy_maybe (AppTy ty1 ty2) = Just (ty1, ty2) -splitAppTy_maybe (NoteTy _ ty) = splitAppTy_maybe ty -splitAppTy_maybe (PredTy p) = splitAppTy_maybe (predTypeRep p) -splitAppTy_maybe (NewTcApp tc tys) = splitAppTy_maybe (newTypeRep tc tys) splitAppTy_maybe (TyConApp tc tys) = case snocView tys of - Nothing -> Nothing - Just (tys',ty') -> Just (mkGenTyConApp tc tys', ty') - -- mkGenTyConApp just in case the tc is a newtype - + Nothing -> Nothing + Just (tys',ty') -> Just (TyConApp tc tys', ty') splitAppTy_maybe other = Nothing splitAppTy :: Type -> (Type, Type) @@ -236,12 +248,9 @@ splitAppTy ty = case splitAppTy_maybe ty of splitAppTys :: Type -> (Type, [Type]) splitAppTys ty = split ty ty [] where + split orig_ty ty args | Just ty' <- coreView ty = split orig_ty ty' args split orig_ty (AppTy ty arg) args = split ty ty (arg:args) - split orig_ty (NoteTy _ ty) args = split orig_ty ty args - split orig_ty (PredTy p) args = split orig_ty (predTypeRep p) args - split orig_ty (NewTcApp tc tc_args) args = split orig_ty (newTypeRep tc tc_args) args - split orig_ty (TyConApp tc tc_args) args = (mkGenTyConApp tc [], tc_args ++ args) - -- mkGenTyConApp just in case the tc is a newtype + split orig_ty (TyConApp tc tc_args) args = (TyConApp tc [], tc_args ++ args) split orig_ty (FunTy ty1 ty2) args = ASSERT( null args ) (TyConApp funTyCon [], [ty1,ty2]) split orig_ty ty args = (orig_ty, args) @@ -263,51 +272,47 @@ isFunTy :: Type -> Bool isFunTy ty = isJust (splitFunTy_maybe ty) splitFunTy :: Type -> (Type, Type) +splitFunTy ty | Just ty' <- coreView ty = splitFunTy ty' splitFunTy (FunTy arg res) = (arg, res) -splitFunTy (NoteTy _ ty) = splitFunTy ty -splitFunTy (PredTy p) = splitFunTy (predTypeRep p) -splitFunTy (NewTcApp tc tys) = splitFunTy (newTypeRep tc tys) -splitFunTy other = pprPanic "splitFunTy" (crudePprType other) +splitFunTy other = pprPanic "splitFunTy" (ppr other) splitFunTy_maybe :: Type -> Maybe (Type, Type) +splitFunTy_maybe ty | Just ty' <- coreView ty = splitFunTy_maybe ty' splitFunTy_maybe (FunTy arg res) = Just (arg, res) -splitFunTy_maybe (NoteTy _ ty) = splitFunTy_maybe ty -splitFunTy_maybe (PredTy p) = splitFunTy_maybe (predTypeRep p) -splitFunTy_maybe (NewTcApp tc tys) = splitFunTy_maybe (newTypeRep tc tys) splitFunTy_maybe other = Nothing splitFunTys :: Type -> ([Type], Type) splitFunTys ty = split [] ty ty where + split args orig_ty ty | Just ty' <- coreView ty = split args orig_ty ty' split args orig_ty (FunTy arg res) = split (arg:args) res res - split args orig_ty (NoteTy _ ty) = split args orig_ty ty - split args orig_ty (PredTy p) = split args orig_ty (predTypeRep p) - split args orig_ty (NewTcApp tc tys) = split args orig_ty (newTypeRep tc tys) split args orig_ty ty = (reverse args, orig_ty) +splitFunTysN :: Int -> Type -> ([Type], Type) +-- Split off exactly n arg tys +splitFunTysN 0 ty = ([], ty) +splitFunTysN n ty = case splitFunTy ty of { (arg, res) -> + case splitFunTysN (n-1) res of { (args, res) -> + (arg:args, res) }} + zipFunTys :: Outputable a => [a] -> Type -> ([(a,Type)], Type) zipFunTys orig_xs orig_ty = split [] orig_xs orig_ty orig_ty where split acc [] nty ty = (reverse acc, nty) + split acc xs nty ty + | Just ty' <- coreView ty = split acc xs nty ty' split acc (x:xs) nty (FunTy arg res) = split ((x,arg):acc) xs res res - split acc xs nty (NoteTy _ ty) = split acc xs nty ty - split acc xs nty (PredTy p) = split acc xs nty (predTypeRep p) - split acc xs nty (NewTcApp tc tys) = split acc xs nty (newTypeRep tc tys) - split acc (x:xs) nty ty = pprPanic "zipFunTys" (ppr orig_xs <+> crudePprType orig_ty) + split acc (x:xs) nty ty = pprPanic "zipFunTys" (ppr orig_xs <+> ppr orig_ty) funResultTy :: Type -> Type +funResultTy ty | Just ty' <- coreView ty = funResultTy ty' funResultTy (FunTy arg res) = res -funResultTy (NoteTy _ ty) = funResultTy ty -funResultTy (PredTy p) = funResultTy (predTypeRep p) -funResultTy (NewTcApp tc tys) = funResultTy (newTypeRep tc tys) -funResultTy ty = pprPanic "funResultTy" (crudePprType ty) +funResultTy ty = pprPanic "funResultTy" (ppr ty) funArgTy :: Type -> Type +funArgTy ty | Just ty' <- coreView ty = funArgTy ty' funArgTy (FunTy arg res) = arg -funArgTy (NoteTy _ ty) = funArgTy ty -funArgTy (PredTy p) = funArgTy (predTypeRep p) -funArgTy (NewTcApp tc tys) = funArgTy (newTypeRep tc tys) -funArgTy ty = pprPanic "funArgTy" (crudePprType ty) +funArgTy ty = pprPanic "funArgTy" (ppr ty) \end{code} @@ -318,23 +323,13 @@ funArgTy ty = pprPanic "funArgTy" (crudePprType 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 - | isNewTyCon tycon - = NewTcApp tycon tys - | otherwise - = ASSERT(not (isSynTyCon tycon)) - TyConApp tycon tys + = TyConApp tycon tys mkTyConTy :: TyCon -> Type mkTyConTy tycon = mkTyConApp tycon [] @@ -352,14 +347,12 @@ tyConAppArgs ty = snd (splitTyConApp ty) splitTyConApp :: Type -> (TyCon, [Type]) splitTyConApp ty = case splitTyConApp_maybe ty of Just stuff -> stuff - Nothing -> pprPanic "splitTyConApp" (crudePprType ty) + Nothing -> pprPanic "splitTyConApp" (ppr ty) splitTyConApp_maybe :: Type -> Maybe (TyCon, [Type]) +splitTyConApp_maybe ty | Just ty' <- coreView ty = splitTyConApp_maybe ty' splitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys) splitTyConApp_maybe (FunTy arg res) = Just (funTyCon, [arg,res]) -splitTyConApp_maybe (NoteTy _ ty) = splitTyConApp_maybe ty -splitTyConApp_maybe (PredTy p) = splitTyConApp_maybe (predTypeRep p) -splitTyConApp_maybe (NewTcApp tc tys) = splitTyConApp_maybe (newTypeRep tc tys) splitTyConApp_maybe other = Nothing \end{code} @@ -368,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 @@ -416,29 +383,46 @@ repType looks through (b) synonyms (c) predicates (d) usage annotations - (e) [recursive] newtypes + (e) all newtypes, including recursive ones 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 (NewTcApp tc tys) = 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. typePrimRep :: Type -> PrimRep typePrimRep ty = case repType ty of TyConApp tc _ -> tyConPrimRep tc FunTy _ _ -> PtrRep - AppTy _ _ -> PtrRep -- ?? + AppTy _ _ -> PtrRep -- See note below TyVarTy _ -> PtrRep - other -> pprPanic "typePrimRep" (crudePprType ty) -\end{code} + other -> pprPanic "typePrimRep" (ppr ty) + -- Types of the form 'f a' must be of kind *, not *#, so + -- we are guaranteed that they are represented by pointers. + -- The reason is that f must have kind *->*, not *->*#, because + -- (we claim) there is no way to constrain f's kind any other + -- way. +\end{code} --------------------------------------------------------------------- @@ -461,19 +445,15 @@ isForAllTy other_ty = False splitForAllTy_maybe :: Type -> Maybe (TyVar, Type) splitForAllTy_maybe ty = splitFAT_m ty where - splitFAT_m (NoteTy _ ty) = splitFAT_m ty - splitFAT_m (PredTy p) = splitFAT_m (predTypeRep p) - splitFAT_m (NewTcApp tc tys) = splitFAT_m (newTypeRep tc tys) - splitFAT_m (ForAllTy tyvar ty) = Just(tyvar, ty) - splitFAT_m _ = Nothing + splitFAT_m ty | Just ty' <- coreView ty = splitFAT_m ty' + splitFAT_m (ForAllTy tyvar ty) = Just(tyvar, ty) + splitFAT_m _ = Nothing splitForAllTys :: Type -> ([TyVar], Type) splitForAllTys ty = split ty ty [] where + split orig_ty ty tvs | Just ty' <- coreView ty = split orig_ty ty' tvs split orig_ty (ForAllTy tv ty) tvs = split ty ty (tv:tvs) - split orig_ty (NoteTy _ ty) tvs = split orig_ty ty tvs - split orig_ty (PredTy p) tvs = split orig_ty (predTypeRep p) tvs - split orig_ty (NewTcApp tc tys) tvs = split orig_ty (newTypeRep tc tys) tvs split orig_ty t tvs = (reverse tvs, orig_ty) dropForAlls :: Type -> Type @@ -492,11 +472,9 @@ the expression. \begin{code} applyTy :: Type -> Type -> Type -applyTy (PredTy p) arg = applyTy (predTypeRep p) arg -applyTy (NewTcApp tc tys) arg = applyTy (newTypeRep tc tys) arg -applyTy (NoteTy _ fun) arg = applyTy fun arg -applyTy (ForAllTy tv ty) arg = substTyWith [tv] [arg] ty -applyTy other arg = panic "applyTy" +applyTy ty arg | Just ty' <- coreView ty = applyTy ty' arg +applyTy (ForAllTy tv ty) arg = substTyWith [tv] [arg] ty +applyTy other arg = panic "applyTy" applyTys :: Type -> [Type] -> Type -- This function is interesting because @@ -518,7 +496,7 @@ applyTys orig_fun_ty arg_tys = substTyWith (take n_args tvs) arg_tys (mkForAllTys (drop n_args tvs) rho_ty) | otherwise -- Too many type args - = ASSERT2( n_tvs > 0, crudePprType orig_fun_ty ) -- Zero case gives infnite loop! + = ASSERT2( n_tvs > 0, ppr orig_fun_ty ) -- Zero case gives infnite loop! applyTys (substTyWith tvs (take n_tvs arg_tys) rho_ty) (drop n_tvs arg_tys) where @@ -551,15 +529,12 @@ mkPredTys preds = map PredTy preds predTypeRep :: PredType -> Type -- Convert a PredType to its "representation type"; -- the post-type-checking type used by all the Core passes of GHC. +-- Unwraps only the outermost level; for example, the result might +-- be a newtype application predTypeRep (IParam _ ty) = ty predTypeRep (ClassP clas tys) = mkTyConApp (classTyCon clas) tys - -- Result might be a NewTcApp, but the consumer will + -- Result might be a newtype application, but the consumer will -- look through that too if necessary - -isPredTy :: Type -> Bool -isPredTy (NoteTy _ ty) = isPredTy ty -isPredTy (PredTy sty) = True -isPredTy _ = False \end{code} @@ -571,43 +546,20 @@ isPredTy _ = False \begin{code} splitRecNewType_maybe :: Type -> Maybe Type --- Newtypes are always represented by a NewTcApp -- Sometimes we want to look through a recursive newtype, and that's what happens here +-- It only strips *one layer* off, so the caller will usually call itself recursively -- Only applied to types of kind *, hence the newtype is always saturated -splitRecNewType_maybe (NoteTy _ ty) = splitRecNewType_maybe ty -splitRecNewType_maybe (NewTcApp tc tys) - | isRecursiveTyCon tc - = ASSERT( tys `lengthIs` tyConArity tc && isNewTyCon tc ) - -- The assert should hold because repType should - -- only be applied to *types* (of kind *) - Just (new_type_rep tc tys) +splitRecNewType_maybe ty | Just ty' <- coreView ty = splitRecNewType_maybe ty' +splitRecNewType_maybe (TyConApp tc tys) + | isNewTyCon tc + = ASSERT( tys `lengthIs` tyConArity tc ) -- splitRecNewType_maybe only be applied + -- to *types* (of kind *) + ASSERT( isRecursiveTyCon tc ) -- Guaranteed by coreView + case newTyConRhs tc of + (tvs, rep_ty) -> ASSERT( length tvs == length tys ) + Just (substTyWith tvs tys rep_ty) + splitRecNewType_maybe other = Nothing - ------------------------------ -newTypeRep :: TyCon -> [Type] -> Type --- A local helper function (not exported) --- Expands a newtype application to --- *either* a vanilla TyConApp (recursive newtype, or non-saturated) --- *or* the newtype representation (otherwise) --- Either way, the result is not a NewTcApp --- --- NB: the returned TyConApp is always deconstructed immediately by the --- caller... a TyConApp with a newtype type constructor never lives --- in an ordinary type -newTypeRep tc tys - | not (isRecursiveTyCon tc), -- Not recursive and saturated - tys `lengthIs` tyConArity tc -- treat as equivalent to expansion - = new_type_rep tc tys - | otherwise - = TyConApp tc tys - -- ToDo: Consider caching this substitution in a NType - ----------------------------- --- 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} @@ -624,26 +576,12 @@ new_type_rep new_tycon tys = ASSERT( tys `lengthIs` tyConArity new_tycon ) typeKind :: Type -> Kind typeKind (TyVarTy tyvar) = tyVarKind tyvar -typeKind (TyConApp tycon tys) = foldr (\_ k -> funResultTy k) (tyConKind tycon) tys -typeKind (NewTcApp tycon tys) = foldr (\_ k -> funResultTy k) (tyConKind tycon) tys +typeKind (TyConApp tycon tys) = foldr (\_ k -> kindFunResult k) (tyConKind tycon) tys typeKind (NoteTy _ ty) = typeKind ty typeKind (PredTy _) = liftedTypeKind -- Predicates are always -- represented by lifted types -typeKind (AppTy fun arg) = funResultTy (typeKind fun) - -typeKind (FunTy arg res) = fix_up (typeKind res) - where - fix_up (TyConApp tycon _) | tycon == typeCon - || tycon == openKindCon = liftedTypeKind - fix_up (NoteTy _ kind) = fix_up kind - fix_up kind = kind - -- The basic story is - -- typeKind (FunTy arg res) = typeKind res - -- But a function is lifted regardless of its result type - -- Hence the strange fix-up. - -- Note that 'res', being the result of a FunTy, can't have - -- a strange kind like (*->*). - +typeKind (AppTy fun arg) = kindFunResult (typeKind fun) +typeKind (FunTy arg res) = liftedTypeKind typeKind (ForAllTy tv ty) = typeKind ty \end{code} @@ -653,30 +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 (NewTcApp 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 @@ -694,6 +616,7 @@ addFreeTyVars ty@(NoteTy (FTVNote _) _) = ty addFreeTyVars ty = NoteTy (FTVNote (tyVarsOfType ty)) ty \end{code} + %************************************************************************ %* * \subsection{TidyType} @@ -709,14 +632,11 @@ It doesn't change the uniques at all, just the print names. tidyTyVarBndr :: TidyEnv -> TyVar -> (TidyEnv, TyVar) tidyTyVarBndr (tidy_env, subst) tyvar = case tidyOccName tidy_env (getOccName name) of - (tidy', occ') -> -- New occname reqd - ((tidy', subst'), tyvar') + (tidy', occ') -> ((tidy', 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 @@ -744,8 +664,6 @@ tidyType env@(tidy_env, subst) ty Just tv' -> TyVarTy tv' go (TyConApp tycon tys) = let args = map go tys in args `seqList` TyConApp tycon args - go (NewTcApp tycon tys) = let args = map go tys - in args `seqList` NewTcApp tycon args go (NoteTy note ty) = (NoteTy $! (go_note note)) $! (go ty) go (PredTy sty) = PredTy (tidyPred env sty) go (AppTy fun arg) = (AppTy $! (go fun)) $! (go arg) @@ -754,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 @@ -783,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} + %************************************************************************ %* * @@ -798,11 +752,9 @@ isUnLiftedType :: Type -> Bool -- They are pretty bogus types, mind you. It would be better never to -- construct them +isUnLiftedType ty | Just ty' <- coreView ty = isUnLiftedType ty' isUnLiftedType (ForAllTy tv ty) = isUnLiftedType ty -isUnLiftedType (NoteTy _ ty) = isUnLiftedType ty isUnLiftedType (TyConApp tc _) = isUnLiftedTyCon tc -isUnLiftedType (PredTy _) = False -- All source types are lifted -isUnLiftedType (NewTcApp tc tys) = isUnLiftedType (newTypeRep tc tys) isUnLiftedType other = False isUnboxedTupleType :: Type -> Bool @@ -826,11 +778,10 @@ this function should be in TcType, but isStrictType is used by DataCon, which is below TcType in the hierarchy, so it's convenient to put it here. \begin{code} +isStrictType (PredTy pred) = isStrictPred pred +isStrictType ty | Just ty' <- coreView ty = isStrictType ty' isStrictType (ForAllTy tv ty) = isStrictType ty -isStrictType (NoteTy _ ty) = isStrictType ty isStrictType (TyConApp tc _) = isUnLiftedTyCon tc -isStrictType (NewTcApp tc tys) = isStrictType (newTypeRep tc tys) -isStrictType (PredTy pred) = isStrictPred pred isStrictType other = False isStrictPred (ClassP clas _) = opt_DictsStrict && not (isNewTyCon (classTyCon clas)) @@ -867,7 +818,6 @@ seqType (FunTy t1 t2) = seqType t1 `seq` seqType t2 seqType (NoteTy note t2) = seqNote note `seq` seqType t2 seqType (PredTy p) = seqPred p seqType (TyConApp tc tys) = tc `seq` seqTypes tys -seqType (NewTcApp tc tys) = tc `seq` seqTypes tys seqType (ForAllTy tv ty) = tv `seq` seqType ty seqTypes :: [Type] -> () @@ -875,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 -> () @@ -886,71 +835,398 @@ seqPred (IParam n ty) = n `seq` seqType ty %************************************************************************ %* * -\subsection{Equality on types} + Equality for Core types + (We don't use instances so that we know where it happens) +%* * +%************************************************************************ + +Note that eqType works right even for partial applications of newtypes. +See Note [Newtype eta] in TyCon.lhs + +\begin{code} +coreEqType :: Type -> Type -> Bool +coreEqType t1 t2 + = eq rn_env t1 t2 + where + rn_env = mkRnEnv2 (mkInScopeSet (tyVarsOfType t1 `unionVarSet` tyVarsOfType t2)) + + 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} + + +%************************************************************************ +%* * + Comparision for source types + (We don't use instances so that we know where it happens) %* * %************************************************************************ -Comparison; don't use instances so that we know where it happens. -Look through newtypes but not usage types. +Note that + tcEqType, tcCmpType +do *not* look through newtypes, PredTypes + +\begin{code} +tcEqType :: Type -> Type -> Bool +tcEqType t1 t2 = isEqual $ cmpType t1 t2 + +tcEqTypes :: [Type] -> [Type] -> Bool +tcEqTypes tys1 tys2 = isEqual $ cmpTypes tys1 tys2 + +tcCmpType :: Type -> Type -> Ordering +tcCmpType t1 t2 = cmpType t1 t2 -Note that eqType can respond 'False' for partial applications of newtypes. -Consider - newtype Parser m a = MkParser (Foogle m a) +tcCmpTypes :: [Type] -> [Type] -> Ordering +tcCmpTypes tys1 tys2 = cmpTypes tys1 tys2 -Does - Monad (Parser m) `eqType` Monad (Foogle m) +tcEqPred :: PredType -> PredType -> Bool +tcEqPred p1 p2 = isEqual $ cmpPred p1 p2 -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. +tcCmpPred :: PredType -> PredType -> Ordering +tcCmpPred p1 p2 = cmpPred p1 p2 + +tcEqTypeX :: RnEnv2 -> Type -> Type -> Bool +tcEqTypeX env t1 t2 = isEqual $ cmpTypeX env t1 t2 +\end{code} + +Now here comes the real worker \begin{code} -eqType t1 t2 = eq_ty emptyVarEnv t1 t2 -eqKind = eqType -- No worries about looking - --- Look through Notes -eq_ty env (NoteTy _ t1) t2 = eq_ty env t1 t2 -eq_ty env t1 (NoteTy _ t2) = eq_ty env t1 t2 - --- Look through PredTy and NewTcApp. This is where the looping danger comes from. --- We don't bother to check for the PredType/PredType case, no good reason --- Hmm: maybe there is a good reason: see the notes below about newtypes -eq_ty env (PredTy sty1) t2 = eq_ty env (predTypeRep sty1) t2 -eq_ty env t1 (PredTy sty2) = eq_ty env t1 (predTypeRep sty2) - --- NB: we *cannot* short-cut the newtype comparison thus: --- eq_ty env (NewTcApp tc1 tys1) (NewTcApp tc2 tys2) --- | (tc1 == tc2) = (eq_tys 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. - -eq_ty env (NewTcApp tc1 tys1) t2 = eq_ty env (newTypeRep tc1 tys1) t2 -eq_ty env t1 (NewTcApp tc2 tys2) = eq_ty env t1 (newTypeRep tc2 tys2) - --- The rest is plain sailing -eq_ty env (TyVarTy tv1) (TyVarTy tv2) = case lookupVarEnv env tv1 of - Just tv1a -> tv1a == tv2 - Nothing -> tv1 == tv2 -eq_ty env (ForAllTy tv1 t1) (ForAllTy tv2 t2) - | tv1 == tv2 = eq_ty (delVarEnv env tv1) t1 t2 - | otherwise = eq_ty (extendVarEnv env tv1 tv2) t1 t2 -eq_ty env (AppTy s1 t1) (AppTy s2 t2) = (eq_ty env s1 s2) && (eq_ty env t1 t2) -eq_ty env (FunTy s1 t1) (FunTy s2 t2) = (eq_ty env s1 s2) && (eq_ty env t1 t2) -eq_ty env (TyConApp tc1 tys1) (TyConApp tc2 tys2) = (tc1 == tc2) && (eq_tys env tys1 tys2) -eq_ty env t1 t2 = False - -eq_tys env [] [] = True -eq_tys env (t1:tys1) (t2:tys2) = (eq_ty env t1 t2) && (eq_tys env tys1 tys2) -eq_tys env tys1 tys2 = False +cmpType :: Type -> Type -> Ordering +cmpType t1 t2 = cmpTypeX rn_env t1 t2 + where + rn_env = mkRnEnv2 (mkInScopeSet (tyVarsOfType t1 `unionVarSet` tyVarsOfType t2)) + +cmpTypes :: [Type] -> [Type] -> Ordering +cmpTypes ts1 ts2 = cmpTypesX rn_env ts1 ts2 + where + rn_env = mkRnEnv2 (mkInScopeSet (tyVarsOfTypes ts1 `unionVarSet` tyVarsOfTypes ts2)) + +cmpPred :: PredType -> PredType -> Ordering +cmpPred p1 p2 = cmpPredX rn_env p1 p2 + where + rn_env = mkRnEnv2 (mkInScopeSet (tyVarsOfPred p1 `unionVarSet` tyVarsOfPred p2)) + +cmpTypeX :: RnEnv2 -> Type -> Type -> Ordering -- Main workhorse +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 +cmpTypeX env (AppTy s1 t1) (AppTy s2 t2) = cmpTypeX env s1 s2 `thenCmp` cmpTypeX env t1 t2 +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 t1 (NoteTy _ t2) = cmpTypeX env t1 t2 + + -- Deal with the rest: TyVarTy < AppTy < FunTy < TyConApp < ForAllTy < PredTy +cmpTypeX env (AppTy _ _) (TyVarTy _) = GT + +cmpTypeX env (FunTy _ _) (TyVarTy _) = GT +cmpTypeX env (FunTy _ _) (AppTy _ _) = GT + +cmpTypeX env (TyConApp _ _) (TyVarTy _) = GT +cmpTypeX env (TyConApp _ _) (AppTy _ _) = GT +cmpTypeX env (TyConApp _ _) (FunTy _ _) = GT + +cmpTypeX env (ForAllTy _ _) (TyVarTy _) = GT +cmpTypeX env (ForAllTy _ _) (AppTy _ _) = GT +cmpTypeX env (ForAllTy _ _) (FunTy _ _) = GT +cmpTypeX env (ForAllTy _ _) (TyConApp _ _) = GT + +cmpTypeX env (PredTy _) t2 = GT + +cmpTypeX env _ _ = LT + +------------- +cmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering +cmpTypesX env [] [] = EQ +cmpTypesX env (t1:tys1) (t2:tys2) = cmpTypeX env t1 t2 `thenCmp` cmpTypesX env tys1 tys2 +cmpTypesX env [] tys = LT +cmpTypesX env ty [] = GT + +------------- +cmpPredX :: RnEnv2 -> PredType -> PredType -> Ordering +cmpPredX env (IParam n1 ty1) (IParam n2 ty2) = (n1 `compare` n2) `thenCmp` cmpTypeX env ty1 ty2 + -- Compare types as well as names for implicit parameters + -- This comparison is used exclusively (I think) for the + -- finite map built in TcSimplify +cmpPredX env (ClassP c1 tys1) (ClassP c2 tys2) = (c1 `compare` c2) `thenCmp` cmpTypesX env tys1 tys2 +cmpPredX env (IParam _ _) (ClassP _ _) = LT +cmpPredX env (ClassP _ _) (IParam _ _) = GT +\end{code} + +PredTypes are used as a FM key in TcSimplify, +so we take the easy path and make them an instance of Ord + +\begin{code} +instance Eq PredType where { (==) = tcEqPred } +instance Ord PredType where { compare = tcCmpPred } +\end{code} + + +%************************************************************************ +%* * + Type substitutions +%* * +%************************************************************************ + +\begin{code} +data TvSubst + = TvSubst InScopeSet -- The in-scope type variables + TvSubstEnv -- The substitution itself + -- See Note [Apply Once] + +{- ---------------------------------------------------------- + Note [Apply Once] + +We use TvSubsts to instantiate things, and we might instantiate + forall a b. ty +\with the types + [a, b], or [b, a]. +So the substition might go [a->b, b->a]. A similar situation arises in Core +when we find a beta redex like + (/\ a /\ b -> e) b a +Then we also end up with a substition that permutes type variables. Other +variations happen to; for example [a -> (a, b)]. + + *************************************************** + *** So a TvSubst must be applied precisely once *** + *************************************************** + +A TvSubst is not idempotent, but, unlike the non-idempotent substitution +we use during unifications, it must not be repeatedly applied. +-------------------------------------------------------------- -} + + +type TvSubstEnv = TyVarEnv Type + -- A TvSubstEnv is used both inside a TvSubst (with the apply-once + -- invariant discussed in Note [Apply Once]), and also independently + -- 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 + +getTvInScope :: TvSubst -> InScopeSet +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 + +extendTvInScope :: TvSubst -> [Var] -> TvSubst +extendTvInScope (TvSubst in_scope env) vars = TvSubst (extendInScopeSetList in_scope vars) env + +extendTvSubst :: TvSubst -> TyVar -> Type -> TvSubst +extendTvSubst (TvSubst in_scope env) tv ty = TvSubst in_scope (extendVarEnv env tv ty) + +extendTvSubstList :: TvSubst -> [TyVar] -> [Type] -> TvSubst +extendTvSubstList (TvSubst in_scope env) tvs tys + = TvSubst in_scope (extendVarEnvList env (tvs `zip` tys)) + +-- 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 + +mkOpenTvSubst :: TvSubstEnv -> TvSubst +mkOpenTvSubst env = TvSubst (mkInScopeSet (tyVarsOfTypes (varEnvElts env))) env + +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. +-- Here we expect that the free vars of the range of the +-- substitution will be empty. +mkTopTvSubst :: [(TyVar, Type)] -> TvSubst +mkTopTvSubst prs = TvSubst emptyInScopeSet (mkVarEnv prs) + +zipTopTvSubst :: [TyVar] -> [Type] -> TvSubst +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 +#ifdef DEBUG + | length tyvars /= length tys + = pprTrace "mkTopTvSubst" (ppr tyvars $$ ppr tys) emptyVarEnv + | otherwise +#endif + = zip_ty_env tyvars tys emptyVarEnv + +-- Later substitutions in the list over-ride earlier ones, +-- but there should be no loops +zip_ty_env [] [] env = env +zip_ty_env (tv:tvs) (ty:tys) env = zip_ty_env tvs tys (extendVarEnv env tv ty) + -- There used to be a special case for when + -- ty == TyVarTy tv + -- (a not-uncommon case) in which case the substitution was dropped. + -- But the type-tidier changes the print-name of a type variable without + -- changing the unique, and that led to a bug. Why? Pre-tidying, we had + -- a type {Foo t}, where Foo is a one-method class. So Foo is really a newtype. + -- And it happened that t was the type variable of the class. Post-tiding, + -- it got turned into {Foo t2}. The ext-core printer expanded this using + -- sourceTypeRep, but that said "Oh, t == t2" because they have the same unique, + -- 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) + = sep[ ptext SLIT(" ppr ins), + nest 2 (ptext SLIT("Env:") <+> ppr env) ] \end{code} +%************************************************************************ +%* * + Performing type substitutions +%* * +%************************************************************************ + +\begin{code} +substTyWith :: [TyVar] -> [Type] -> Type -> Type +substTyWith tvs tys = ASSERT( length tvs == length tys ) + substTy (zipOpenTvSubst tvs tys) + +substTy :: TvSubst -> Type -> Type +substTy subst ty | isEmptyTvSubst subst = ty + | otherwise = subst_ty subst ty + +substTys :: TvSubst -> [Type] -> [Type] +substTys subst tys | isEmptyTvSubst subst = tys + | otherwise = map (subst_ty subst) tys + +substTheta :: TvSubst -> ThetaType -> ThetaType +substTheta subst theta + | isEmptyTvSubst subst = theta + | otherwise = map (substPred subst) theta + +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 + = go ty + where + go (TyVarTy tv) = substTyVar subst tv + go (TyConApp tc tys) = let args = map go tys + in args `seqList` TyConApp tc args + + go (PredTy p) = PredTy $! (substPred subst p) + + go (NoteTy (FTVNote _) ty2) = go ty2 -- Discard the free tyvar note + + go (FunTy arg res) = (FunTy $! (go arg)) $! (go res) + go (AppTy fun arg) = mkAppTy (go fun) $! (go arg) + -- The mkAppTy smart constructor is important + -- we might be replacing (a Int), represented with App + -- by [Int], represented with TyConApp + go (ForAllTy tv ty) = case substTyVarBndr subst tv of + (subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty) + +substTyVar :: TvSubst -> TyVar -> Type +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 + -- But we *must* zap any current substitution for the variable. + -- For example: + -- (\x.e) with id_subst = [x |-> e'] + -- Here we must simply zap the substitution for x + -- + -- The new_id isn't cloned, but it may have a different type + -- etc, so we must return it, not the old id + = (TvSubst (in_scope `extendInScopeSet` new_var) + (delVarEnv env old_var), + new_var) + + | otherwise -- The new binder is in scope so + -- we'd better rename it away from the in-scope variables + -- Extending the substitution to do this renaming also + -- has the (correct) effect of discarding any existing + -- substitution for that variable + = (TvSubst (in_scope `extendInScopeSet` new_var) + (extendVarEnv env old_var (TyVarTy new_var)), + new_var) + where + new_var = uniqAway in_scope old_var + -- The uniqAway part makes sure the new variable is not already in scope +\end{code}