[commit: ghc] master: Fix reduceTyFamApp_maybe (fd46acf)
git at git.haskell.org
git at git.haskell.org
Tue Nov 4 10:38:06 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/fd46acf1c30d81ce0ac676c5ca7ffe6e3c82ad25/ghc
>---------------------------------------------------------------
commit fd46acf1c30d81ce0ac676c5ca7ffe6e3c82ad25
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Wed Oct 29 16:30:05 2014 +0000
Fix reduceTyFamApp_maybe
This function previously would expand *data* families even when it was asked
for a *Nominal* coercion. This patch fixes it, and adds comments.
>---------------------------------------------------------------
fd46acf1c30d81ce0ac676c5ca7ffe6e3c82ad25
compiler/types/FamInstEnv.lhs | 46 ++++++++++++++++++++++++++++++++-----------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/compiler/types/FamInstEnv.lhs b/compiler/types/FamInstEnv.lhs
index 7fe35ff..bc21e2e 100644
--- a/compiler/types/FamInstEnv.lhs
+++ b/compiler/types/FamInstEnv.lhs
@@ -361,7 +361,8 @@ extendFamInstEnvList :: FamInstEnv -> [FamInst] -> FamInstEnv
extendFamInstEnvList inst_env fis = foldl extendFamInstEnv inst_env fis
extendFamInstEnv :: FamInstEnv -> FamInst -> FamInstEnv
-extendFamInstEnv inst_env ins_item@(FamInst {fi_fam = cls_nm})
+extendFamInstEnv inst_env
+ ins_item@(FamInst {fi_fam = cls_nm})
= addToUFM_C add inst_env cls_nm (FamIE [ins_item])
where
add (FamIE items) _ = FamIE (ins_item:items)
@@ -789,18 +790,33 @@ The lookupFamInstEnv function does a nice job for *open* type families,
but we also need to handle closed ones when normalising a type:
\begin{code}
-reduceTyFamApp_maybe :: FamInstEnvs -> Role -> TyCon -> [Type] -> Maybe (Coercion, Type)
+reduceTyFamApp_maybe :: FamInstEnvs
+ -> Role -- Desired role of result coercion
+ -> TyCon -> [Type]
+ -> Maybe (Coercion, Type)
-- Attempt to do a *one-step* reduction of a type-family application
+-- but *not* newtypes
+-- Works on type-synonym families always; data-families only if
+-- the role we seek is representational
-- It first normalises the type arguments, wrt functions but *not* newtypes,
--- to be sure that nested calls like
--- F (G Int)
--- are correctly reduced
+-- to be sure that nested calls like
+-- F (G Int)
+-- are correctly reduced
--
-- The TyCon can be oversaturated.
-- Works on both open and closed families
reduceTyFamApp_maybe envs role tc tys
- | isOpenFamilyTyCon tc
+ | Phantom <- role
+ = Nothing
+
+ | case role of
+ Representational -> isOpenFamilyTyCon tc
+ _ -> isOpenSynFamilyTyCon tc
+ -- If we seek a representational coercion
+ -- (e.g. the call in topNormaliseType_maybe) then we can
+ -- unwrap data families as well as type-synonym families;
+ -- otherwise only type-synonym families
, [FamInstMatch { fim_instance = fam_inst
, fim_tys = inst_tys }] <- lookupFamInstEnv envs tc ntys
= let ax = famInstAxiom fam_inst
@@ -927,12 +943,18 @@ topNormaliseType_maybe env ty
---------------
normaliseTcApp :: FamInstEnvs -> Role -> TyCon -> [Type] -> (Coercion, Type)
+-- See comments on normaliseType for the arguments of this function
normaliseTcApp env role tc tys
+ | isTypeSynonymTyCon tc
+ , (co1, ntys) <- normaliseTcArgs env role tc tys
+ , Just (tenv, rhs, ntys') <- tcExpandTyCon_maybe tc ntys
+ , (co2, ninst_rhs) <- normaliseType env role (Type.substTy (mkTopTvSubst tenv) rhs)
+ = if isReflCo co2 then (co1, mkTyConApp tc ntys)
+ else (co1 `mkTransCo` co2, mkAppTys ninst_rhs ntys')
+
| Just (first_co, ty') <- reduceTyFamApp_maybe env role tc tys
- = let -- A reduction is possible
- (rest_co,nty) = normaliseType env role ty'
- in
- (first_co `mkTransCo` rest_co, nty)
+ , (rest_co,nty) <- normaliseType env role ty'
+ = (first_co `mkTransCo` rest_co, nty)
| otherwise -- No unique matching family instance exists;
-- we do not do anything
@@ -958,10 +980,10 @@ normaliseType :: FamInstEnvs -- environment with family instances
-> (Coercion, Type) -- (coercion,new type), where
-- co :: old-type ~ new_type
-- Normalise the input type, by eliminating *all* type-function redexes
+-- but *not* newtypes (which are visible to the programmer)
-- Returns with Refl if nothing happens
+-- Try to not to disturb type syonyms if possible
-normaliseType env role ty
- | Just ty' <- coreView ty = normaliseType env role ty'
normaliseType env role (TyConApp tc tys)
= normaliseTcApp env role tc tys
normaliseType _env role ty@(LitTy {}) = (Refl role ty, ty)
More information about the ghc-commits
mailing list