diff options
author | Bartosz Nitka <niteria@gmail.com> | 2016-05-10 05:32:28 -0700 |
---|---|---|
committer | Bartosz Nitka <niteria@gmail.com> | 2016-05-10 05:33:52 -0700 |
commit | b58b0e18a568bbf6381a85eea7adc72679355671 (patch) | |
tree | 334bf7fd0d3aa80ee592bc8daab57ce304dc7801 /compiler/types | |
parent | 4ac0e815739f6362c2815dd3ae531055a095d6a9 (diff) | |
download | haskell-b58b0e18a568bbf6381a85eea7adc72679355671.tar.gz |
Make simplifyInstanceContexts deterministic
simplifyInstanceContexts used cmpType which is nondeterministic
for canonicalising typeclass constraints in derived instances.
Following changes make it deterministic as explained by the
Note [Deterministic simplifyInstanceContexts].
Test Plan: ./validate
Reviewers: simonmar, goldfire, simonpj, austin, bgamari
Reviewed By: simonpj
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2173
GHC Trac Issues: #4012
Diffstat (limited to 'compiler/types')
-rw-r--r-- | compiler/types/Type.hs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/compiler/types/Type.hs b/compiler/types/Type.hs index 49c72678d2..124015f2c3 100644 --- a/compiler/types/Type.hs +++ b/compiler/types/Type.hs @@ -223,6 +223,7 @@ import FastString import Pair import ListSetOps import Digraph +import Unique ( nonDetCmpUnique ) import Maybes ( orElse ) import Data.Maybe ( isJust, mapMaybe ) @@ -2086,6 +2087,16 @@ eqVarBndrs _ _ _= Nothing -- Now here comes the real worker +{- +Note [cmpType nondeterminism] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +cmpType is implemented in terms of cmpTypeX. cmpTypeX uses cmpTc which +compares TyCons by their Unique value. Using Uniques for ordering leads +to nondeterminism. We hit the same problem in the TyVarTy case, comparing +type variables is nondeterministic, note the call to nonDetCmpVar in cmpTypeX. +See Note [Unique Determinism] for more details. +-} + cmpType :: Type -> Type -> Ordering cmpType t1 t2 -- we know k1 and k2 have the same kind, because they both have kind *. @@ -2148,7 +2159,7 @@ cmpTypeX env orig_t1 orig_t2 = | Just t2' <- coreViewOneStarKind t2 = go env t1 t2' go env (TyVarTy tv1) (TyVarTy tv2) - = liftOrdering $ rnOccL env tv1 `compare` rnOccR env tv2 + = liftOrdering $ rnOccL env tv1 `nonDetCmpVar` rnOccR env tv2 go env (ForAllTy (Named tv1 _) t1) (ForAllTy (Named tv2 _) t2) = go env (tyVarKind tv1) (tyVarKind tv2) `thenCmpTy` go (rnBndr2 env tv1 tv2) t1 t2 @@ -2200,10 +2211,11 @@ cmpTypesX _ _ [] = GT -- | Compare two 'TyCon's. NB: This should /never/ see the "star synonyms", -- as recognized by Kind.isStarKindSynonymTyCon. See Note -- [Kind Constraint and kind *] in Kind. +-- See Note [cmpType nondeterminism] cmpTc :: TyCon -> TyCon -> Ordering cmpTc tc1 tc2 = ASSERT( not (isStarKindSynonymTyCon tc1) && not (isStarKindSynonymTyCon tc2) ) - u1 `compare` u2 + u1 `nonDetCmpUnique` u2 where u1 = tyConUnique tc1 u2 = tyConUnique tc2 |