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,
tidyTyVarBndr, tidyFreeTyVars,
tidyOpenTyVar, tidyOpenTyVars,
tidyTopType, tidyPred,
+ tidyKind,
-- Comparison
coreEqType, tcEqType, tcEqTypes, tcCmpType, tcCmpTypes,
TvSubst(..), emptyTvSubst, -- Representation visible to a few friends
mkTvSubst, mkOpenTvSubst, zipOpenTvSubst, zipTopTvSubst, mkTopTvSubst, notElemTvSubst,
getTvSubstEnv, setTvSubstEnv, getTvInScope, extendTvInScope,
- extendTvSubst, extendTvSubstList, isInScope, composeTvSubst,
+ 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,
-- 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 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 )
-- 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,
-- 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}
= 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
= 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)
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 []
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
\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.
-- (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}
-- 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}
~~~~~~~~~~~~~~~~~~~~~~~~
\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
addFreeTyVars ty = NoteTy (FTVNote (tyVarsOfType ty)) ty
\end{code}
+
%************************************************************************
%* *
\subsection{TidyType}
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
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
\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}
+
%************************************************************************
%* *
seqTypes (ty:tys) = seqType ty `seq` seqTypes tys
seqNote :: TyNote -> ()
-seqNote (SynNote ty) = seqType ty
seqNote (FTVNote set) = sizeUniqSet set `seq` ()
seqPred :: PredType -> ()
%************************************************************************
%* *
- 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
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
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
-- 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
+ -- *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
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.
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
-- 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)
\begin{code}
substTyWith :: [TyVar] -> [Type] -> Type -> Type
-substTyWith tvs tys = substTy (zipOpenTvSubst tvs tys)
+substTyWith tvs tys = ASSERT( length tvs == length tys )
+ substTy (zipOpenTvSubst tvs tys)
substTy :: TvSubst -> Type -> Type
substTy subst ty | isEmptyTvSubst subst = ty
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
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 (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)
(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