summaryrefslogtreecommitdiff
path: root/compiler/types
diff options
context:
space:
mode:
authorBartosz Nitka <niteria@gmail.com>2016-05-10 05:32:28 -0700
committerBartosz Nitka <niteria@gmail.com>2016-05-10 05:33:52 -0700
commitb58b0e18a568bbf6381a85eea7adc72679355671 (patch)
tree334bf7fd0d3aa80ee592bc8daab57ce304dc7801 /compiler/types
parent4ac0e815739f6362c2815dd3ae531055a095d6a9 (diff)
downloadhaskell-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.hs16
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