diff options
author | Bartosz Nitka <niteria@gmail.com> | 2015-10-27 10:19:48 -0500 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2015-10-27 10:19:54 -0500 |
commit | ffcdd84f86727c1621be0a0e522eb6a3a64e479f (patch) | |
tree | 248f97aeb7af6185a78ebeb0bf9baea65681953e /compiler/iface | |
parent | dc13467347fa9bf9e1a70389a2eccd9bd4853d21 (diff) | |
download | haskell-ffcdd84f86727c1621be0a0e522eb6a3a64e479f.tar.gz |
Sort field labels before fingerprint hashing
`fsEnvElts :: FastStringEnv a -> [a]` returns a list of `[a]` in the order of
`Unique`s which is arbitrary. In this case it gives a list of record fields in
arbitrary order, from which we then extract the field labels to contribute to
the record fingerprint. The arbitrary ordering of field labels introduces
unnecessary nondeterminism in interface files as demonstrated by the test case.
We sort `FastString` here. It's safe, because the only way that the `Unique`
associated with the `FastString` is used in comparison is for equality. If the
`Unique`s are different it fallbacks to comparing the actual `ByteString`.
Reviewed By: ezyang, thomie, bgamari, austin
Differential Revision: https://phabricator.haskell.org/D1373
GHC Trac Issues: #4012
Diffstat (limited to 'compiler/iface')
-rw-r--r-- | compiler/iface/MkIface.hs | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/compiler/iface/MkIface.hs b/compiler/iface/MkIface.hs index 66a885bb6d..d4b764b613 100644 --- a/compiler/iface/MkIface.hs +++ b/compiler/iface/MkIface.hs @@ -1700,7 +1700,14 @@ tyConToIfaceDecl env tycon ifaceOverloaded flds = case fsEnvElts flds of fl:_ -> flIsOverloaded fl [] -> False - ifaceFields flds = map flLabel $ fsEnvElts flds + ifaceFields flds = sort $ map flLabel $ fsEnvElts flds + -- We need to sort the labels because they come out + -- of FastStringEnv in arbitrary order, because + -- FastStringEnv is keyed on Uniques. + -- Sorting FastString is ok here, because Uniques + -- are only used for equality checks in the Ord + -- instance for FastString. + -- See Note [Unique Determinism] in Unique. toIfaceBang :: TidyEnv -> HsImplBang -> IfaceBang toIfaceBang _ HsLazy = IfNoBang |