summaryrefslogtreecommitdiff
path: root/compiler/types/InstEnv.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/types/InstEnv.hs')
-rw-r--r--compiler/types/InstEnv.hs33
1 files changed, 24 insertions, 9 deletions
diff --git a/compiler/types/InstEnv.hs b/compiler/types/InstEnv.hs
index e214f12a65..a8b5f0f8ff 100644
--- a/compiler/types/InstEnv.hs
+++ b/compiler/types/InstEnv.hs
@@ -41,7 +41,7 @@ import Unify
import Outputable
import ErrUtils
import BasicTypes
-import UniqFM
+import UniqDFM
import Util
import Id
import Data.Data ( Data )
@@ -330,7 +330,21 @@ or, to put it another way, we have
-}
---------------------------------------------------
-type InstEnv = UniqFM ClsInstEnv -- Maps Class to instances for that class
+{-
+Note [InstEnv determinism]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+We turn InstEnvs into a list in some places that don't directly affect
+the ABI. That happens when we create output for `:info`.
+Unfortunately that nondeterminism is nonlocal and it's hard to tell what it
+affects without following a chain of functions. It's also easy to accidentally
+make that nondeterminism affect the ABI. Furthermore the envs should be
+relatively small, so it should be free to use deterministic maps here.
+Testing with nofib and validate detected no difference between UniqFM and
+UniqDFM. See also Note [Deterministic UniqFM]
+-}
+
+type InstEnv = UniqDFM ClsInstEnv -- Maps Class to instances for that class
+ -- See Note [InstEnv determinism]
-- | 'InstEnvs' represents the combination of the global type class instance
-- environment, the local type class instance environment, and the set of
@@ -365,10 +379,11 @@ instance Outputable ClsInstEnv where
-- the dfun type.
emptyInstEnv :: InstEnv
-emptyInstEnv = emptyUFM
+emptyInstEnv = emptyUDFM
instEnvElts :: InstEnv -> [ClsInst]
-instEnvElts ie = [elt | ClsIE elts <- eltsUFM ie, elt <- elts]
+instEnvElts ie = [elt | ClsIE elts <- eltsUDFM ie, elt <- elts]
+ -- See Note [InstEnv determinism]
-- | Test if an instance is visible, by checking that its origin module
-- is in 'VisibleOrphanModules'.
@@ -388,7 +403,7 @@ classInstances :: InstEnvs -> Class -> [ClsInst]
classInstances (InstEnvs { ie_global = pkg_ie, ie_local = home_ie, ie_visible = vis_mods }) cls
= get home_ie ++ get pkg_ie
where
- get env = case lookupUFM env cls of
+ get env = case lookupUDFM env cls of
Just (ClsIE insts) -> filter (instIsVisible vis_mods) insts
Nothing -> []
@@ -397,20 +412,20 @@ classInstances (InstEnvs { ie_global = pkg_ie, ie_local = home_ie, ie_visible =
memberInstEnv :: InstEnv -> ClsInst -> Bool
memberInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm } ) =
maybe False (\(ClsIE items) -> any (identicalClsInstHead ins_item) items)
- (lookupUFM inst_env cls_nm)
+ (lookupUDFM inst_env cls_nm)
extendInstEnvList :: InstEnv -> [ClsInst] -> InstEnv
extendInstEnvList inst_env ispecs = foldl extendInstEnv inst_env ispecs
extendInstEnv :: InstEnv -> ClsInst -> InstEnv
extendInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm })
- = addToUFM_C add inst_env cls_nm (ClsIE [ins_item])
+ = addToUDFM_C add inst_env cls_nm (ClsIE [ins_item])
where
add (ClsIE cur_insts) _ = ClsIE (ins_item : cur_insts)
deleteFromInstEnv :: InstEnv -> ClsInst -> InstEnv
deleteFromInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm })
- = adjustUFM adjust inst_env cls_nm
+ = adjustUDFM adjust inst_env cls_nm
where
adjust (ClsIE items) = ClsIE (filterOut (identicalClsInstHead ins_item) items)
@@ -702,7 +717,7 @@ lookupInstEnv' ie vis_mods cls tys
all_tvs = all isNothing rough_tcs
--------------
- lookup env = case lookupUFM env cls of
+ lookup env = case lookupUDFM env cls of
Nothing -> ([],[]) -- No instances for this class
Just (ClsIE insts) -> find [] [] insts