diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2018-08-31 11:33:08 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2018-08-31 12:56:44 +0100 |
commit | 565ef4cc036905f9f9801c1e775236bb007b026c (patch) | |
tree | 75025acdba91366b02d8e432cb57d18271d460b5 /compiler/typecheck/TcMType.hs | |
parent | fda2ea5830176236380a6976dfd0d5802395c6a9 (diff) | |
download | haskell-565ef4cc036905f9f9801c1e775236bb007b026c.tar.gz |
Remove knot-tying bug in TcHsSyn.zonkTyVarOcc
There was a subtle knot-tying bug in TcHsSyn.zonkTyVarOcc, revealed
in Trac #15552.
I fixed it by
* Eliminating the short-circuiting optimisation in zonkTyVarOcc,
instead adding a finite map to get sharing of zonked unification
variables.
See Note [Sharing when zonking to Type] in TcHsSyn
* On the way I /added/ the short-circuiting optimisation to
TcMType.zonkTcTyVar, which has no such problem. This turned
out (based on non-systematic measurements) to be a modest win.
See Note [Sharing in zonking] in TcMType
On the way I renamed some of the functions in TcHsSyn:
* Ones ending in "X" (like zonkTcTypeToTypeX) take a ZonkEnv
* Ones that do not end in "x" (like zonkTcTypeToType), don't.
Instead they whiz up an empty ZonkEnv.
Diffstat (limited to 'compiler/typecheck/TcMType.hs')
-rw-r--r-- | compiler/typecheck/TcMType.hs | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/compiler/typecheck/TcMType.hs b/compiler/typecheck/TcMType.hs index c6e23e5ff8..642a16abbb 100644 --- a/compiler/typecheck/TcMType.hs +++ b/compiler/typecheck/TcMType.hs @@ -72,7 +72,7 @@ module TcMType ( quantifyTyVars, zonkTcTyCoVarBndr, zonkTcTyVarBinder, zonkTcType, zonkTcTypes, zonkCo, - zonkTyCoVarKind, zonkTcTypeMapper, + zonkTyCoVarKind, zonkEvVar, zonkWC, zonkSimples, zonkId, zonkCoVar, @@ -1596,7 +1596,10 @@ zonkTcTyVar tv -> do { cts <- readMutVar ref ; case cts of Flexi -> zonk_kind_and_return - Indirect ty -> zonkTcType ty } + Indirect ty -> do { zty <- zonkTcType ty + ; writeTcRef ref (Indirect zty) + -- See Note [Sharing in zonking] + ; return zty } } | otherwise -- coercion variable = zonk_kind_and_return @@ -1622,7 +1625,26 @@ zonkTyVarTyVarPairs prs do_one (nm, tv) = do { tv' <- zonkTcTyVarToTyVar tv ; return (nm, tv') } -{- +{- Note [Sharing in zonking] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have + alpha :-> beta :-> gamma :-> ty +where the ":->" means that the unification variable has been +filled in with Indirect. Then when zonking alpha, it'd be nice +to short-circuit beta too, so we end up with + alpha :-> zty + beta :-> zty + gamma :-> zty +where zty is the zonked version of ty. That way, if we come across +beta later, we'll have less work to do. (And indeed the same for +alpha.) + +This is easily achieved: just overwrite (Indirect ty) with (Indirect +zty). Non-systematic perf comparisons suggest that this is a modest +win. + +But c.f Note [Sharing when zonking to Type] in TcHsSyn. + %************************************************************************ %* * Tidying |