[commit: ghc] master: Fix an outright bug in expandTypeSynonyms (286dc02)
git at git.haskell.org
git at git.haskell.org
Wed Mar 2 15:22:54 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/286dc021ef515d02453cd5e31774b852d3a1310f/ghc
>---------------------------------------------------------------
commit 286dc021ef515d02453cd5e31774b852d3a1310f
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Wed Mar 2 15:12:12 2016 +0000
Fix an outright bug in expandTypeSynonyms
The bug was in this code:
go subst (TyConApp tc tys)
| Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys
= let subst' = unionTCvSubst subst (mkTvSubstPrs tenv) in
go subst' (mkAppTys rhs tys')
This is wrong in two ways.
* It is wrong to apply the expanded substitution to tys',
* The unionTCvSubst is utterly wrong; after all, rhs is
completely separate, and the union makes a non-idempotent
substitution.
It was the non-idempotency that gave the Lint failure in Trac #11665,
when there was a type synonym whose RHS mentioned another type synonym,
something like
type T a b = a -> b
type S x y = T y x
It only affects SpecConstr because that's about the only place where
expandTypeSyonym is called. I tried to trigger the failure with a
simple test case, but failed, so I have not added a regression test.
Fortunately the solution is very simple and solid.
FWIW, the culprit was 674654, "Add kind equalities to GHC".
>---------------------------------------------------------------
286dc021ef515d02453cd5e31774b852d3a1310f
compiler/types/Type.hs | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/compiler/types/Type.hs b/compiler/types/Type.hs
index 78c20a9..b71bba3 100644
--- a/compiler/types/Type.hs
+++ b/compiler/types/Type.hs
@@ -327,14 +327,26 @@ expandTypeSynonyms :: Type -> Type
-- 'expandTypeSynonyms' only expands out type synonyms mentioned in the type,
-- not in the kinds of any TyCon or TyVar mentioned in the type.
expandTypeSynonyms ty
- = go (mkEmptyTCvSubst (mkTyCoInScopeSet [ty] [])) ty
+ = go (mkEmptyTCvSubst in_scope) ty
where
+ in_scope = mkInScopeSet (tyCoVarsOfType ty)
+
go subst (TyConApp tc tys)
- | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys
- = let subst' = unionTCvSubst subst (mkTvSubstPrs tenv) in
- go subst' (mkAppTys rhs tys')
+ | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc expanded_tys
+ = let subst' = mkTvSubst in_scope (mkVarEnv tenv)
+ -- Make a fresh substitution; rhs has nothing to
+ -- do with anything that has happened so far
+ -- NB: if you make changes here, be sure to build an
+ -- /idempotent/ substitution, even in the nested case
+ -- type T a b = a -> b
+ -- type S x y = T y x
+ -- (Trac #11665)
+ in mkAppTys (go subst' rhs) tys'
| otherwise
- = TyConApp tc (map (go subst) tys)
+ = TyConApp tc expanded_tys
+ where
+ expanded_tys = (map (go subst) tys)
+
go _ (LitTy l) = LitTy l
go subst (TyVarTy tv) = substTyVar subst tv
go subst (AppTy t1 t2) = mkAppTy (go subst t1) (go subst t2)
More information about the ghc-commits
mailing list