[commit: ghc] master: Don't use deriveUnique *twice* in flattenTys. (a0cea7b)
git at git.haskell.org
git at git.haskell.org
Tue Mar 3 18:43:20 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/a0cea7ba9f14a193f31f057371d104c2dc0b7d80/ghc
>---------------------------------------------------------------
commit a0cea7ba9f14a193f31f057371d104c2dc0b7d80
Author: Richard Eisenberg <eir at cis.upenn.edu>
Date: Tue Mar 3 12:55:54 2015 -0500
Don't use deriveUnique *twice* in flattenTys.
Previously, we used deriveUnique and then uniqAway. This worked
doubly hard to avoid clashes. Doing just uniqAway is enough.
This commit also includes clarifying comments.
>---------------------------------------------------------------
a0cea7ba9f14a193f31f057371d104c2dc0b7d80
compiler/types/FamInstEnv.hs | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/compiler/types/FamInstEnv.hs b/compiler/types/FamInstEnv.hs
index b121c73..690cab2 100644
--- a/compiler/types/FamInstEnv.hs
+++ b/compiler/types/FamInstEnv.hs
@@ -986,6 +986,24 @@ means replacing all top-level uses of type functions with fresh variables,
taking care to preserve sharing. That is, the type (Either (F a b) (F a b)) should
flatten to (Either c c), never (Either c d).
+Here is a nice example of why it's all necessary:
+
+ type family F a b where
+ F Int Bool = Char
+ F a b = Double
+ type family G a -- open, no instances
+
+How do we reduce (F (G Float) (G Float))? The first equation clearly doesn't match,
+while the second equation does. But, before reducing, we must make sure that the
+target can never become (F Int Bool). Well, no matter what G Float becomes, it
+certainly won't become *both* Int and Bool, so indeed we're safe reducing
+(F (G Float) (G Float)) to Double.
+
+This is necessary not only to get more reductions, but for substitutivity. If
+we have (F x x), we can see that (F x x) can reduce to Double. So, it had better
+be the case that (F blah blah) can reduce to Double, no matter what (blah) is!
+Flattening as done below ensures this.
+
Defined here because of module dependencies.
-}
@@ -1044,10 +1062,11 @@ coreFlattenTyFamApp in_scope m fam_tc fam_args
= case lookupTypeMap m fam_ty of
Just tv -> (m, tv)
-- we need fresh variables here, but this is called far from
- -- any good source of uniques. So, we generate one from thin
- -- air, using the arbitrary prime number 71 as a seed
- Nothing -> let tyvar_unique = deriveUnique (getUnique fam_tc) 71
- tyvar_name = mkSysTvName tyvar_unique (fsLit "fl")
+ -- any good source of uniques. So, we just use the fam_tc's unique
+ -- and trust uniqAway to avoid clashes. Recall that the in_scope set
+ -- contains *all* tyvars, even locally bound ones elsewhere in the
+ -- overall type, so this really is fresh.
+ Nothing -> let tyvar_name = mkSysTvName (getUnique fam_tc) (fsLit "fl")
tv = uniqAway in_scope $ mkTyVar tyvar_name (typeKind fam_ty)
m' = extendTypeMap m fam_ty tv in
(m', tv)
More information about the ghc-commits
mailing list