X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcGadt.lhs;h=5bad13e0a4bf0e043be38a0fef55da50e9d1289d;hb=366e8db02ab7a5bb5316699bff397d06e47891b2;hp=4e71827d01b394463fccb11fb25ac9bd9570c529;hpb=ab22f4e6456820c1b5169d75f5975a94e61f54ce;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcGadt.lhs b/compiler/typecheck/TcGadt.lhs index 4e71827..5bad13e 100644 --- a/compiler/typecheck/TcGadt.lhs +++ b/compiler/typecheck/TcGadt.lhs @@ -21,7 +21,6 @@ module TcGadt ( import HsSyn import Coercion -import Type import TypeRep import DataCon import Var @@ -31,11 +30,11 @@ import ErrUtils import Maybes import Control.Monad import Outputable +import TcType #ifdef DEBUG import Unique import UniqFM -import TcType #endif \end{code} @@ -48,6 +47,8 @@ import TcType \begin{code} data Refinement = Reft InScopeSet InternalReft + +type InternalReft = TyVarEnv (Coercion, Type) -- INVARIANT: a->(co,ty) then co :: (a:=:ty) -- Not necessarily idemopotent @@ -60,16 +61,17 @@ emptyRefinement :: Refinement emptyRefinement = (Reft emptyInScopeSet emptyVarEnv) -refineType :: Refinement -> Type -> (HsWrapper, Type) +refineType :: Refinement -> Type -> Maybe (Coercion, Type) -- Apply the refinement to the type. -- If (refineType r ty) = (co, ty') -- Then co :: ty:=:ty' +-- Nothing => the refinement does nothing to this type refineType (Reft in_scope env) ty | not (isEmptyVarEnv env), -- Common case any (`elemVarEnv` env) (varSetElems (tyVarsOfType ty)) - = (WpCo (substTy co_subst ty), substTy tv_subst ty) + = Just (substTy co_subst ty, substTy tv_subst ty) | otherwise - = (idHsWrapper, ty) -- The type doesn't mention any refined type variables + = Nothing -- The type doesn't mention any refined type variables where tv_subst = mkTvSubst in_scope (mapVarEnv snd env) co_subst = mkTvSubst in_scope (mapVarEnv fst env) @@ -78,11 +80,11 @@ refineResType :: Refinement -> Type -> (HsWrapper, Type) -- Like refineType, but returns the 'sym' coercion -- If (refineResType r ty) = (co, ty') -- Then co :: ty':=:ty +-- It's convenient to return a HsWrapper here refineResType reft ty = case refineType reft ty of - (WpCo co, ty1) -> (WpCo (mkSymCoercion co), ty1) - (id_co, ty1) -> ASSERT( isIdHsWrapper id_co ) - (idHsWrapper, ty1) + Just (co, ty1) -> (WpCo (mkSymCoercion co), ty1) + Nothing -> (idHsWrapper, ty) \end{code} @@ -139,7 +141,7 @@ gadtRefine (Reft in_scope env1) ex_tvs co_vars -- Precondition: fvs( co_vars ) # env1 -- That is, the kinds of the co_vars are a --- fixed point of the incoming refinement +-- fixed point of the incoming refinement = ASSERT2( not $ any (`elemVarEnv` env1) (varSetElems $ tyVarsOfTypes $ map tyVarKind co_vars), ppr env1 $$ ppr co_vars $$ ppr (map tyVarKind co_vars) ) @@ -157,9 +159,11 @@ gadtRefine (Reft in_scope env1) where tv_set = mkVarSet ex_tvs in_scope' = foldr extend in_scope co_vars + + -- For each co_var, add it *and* the tyvars it mentions, to in_scope extend co_var in_scope - = extendInScopeSetSet (extendInScopeSet in_scope co_var) - (tyVarsOfType (tyVarKind co_var)) + = extendInScopeSetSet in_scope $ + extendVarSet (tyVarsOfType (tyVarKind co_var)) co_var do_one reft co_var = unify reft (TyVarTy co_var) ty1 ty2 where @@ -206,15 +210,13 @@ fixTvCoEnv in_scope env where fixpt = mapVarEnv step env - step (co, ty) = (co1, ty') + step (co, ty) = case refineType (Reft in_scope fixpt) ty of + Nothing -> (co, ty) + Just (co', ty') -> (mkTransCoercion co co', ty') -- Apply fixpt one step: -- Use refineType to get a substituted type, ty', and a coercion, co_fn, -- which justifies the substitution. If the coercion is not the identity -- then use transitivity with the original coercion - where - (co_fn, ty') = refineType (Reft in_scope fixpt) ty - co1 | WpCo co'' <- co_fn = mkTransCoercion co co'' - | otherwise = ASSERT( isIdHsWrapper co_fn ) co ----------------------------- fixTvSubstEnv :: InScopeSet -> TvSubstEnv -> TvSubstEnv @@ -254,11 +256,6 @@ tryToBind tv_set tv | tv `elemVarSet` tv_set = BindMe %************************************************************************ \begin{code} -type InternalReft = TyVarEnv (Coercion, Type) - --- INVARIANT: a->(co,ty) then co :: (a:=:ty) --- Not necessarily idemopotent - #ifdef DEBUG badReftElts :: InternalReft -> [(Unique, (Coercion,Type))] -- Return the BAD elements of the refinement