diff options
author | Bartosz Nitka <niteria@gmail.com> | 2015-10-30 23:40:21 +0100 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2015-10-30 23:40:34 +0100 |
commit | a5cb27f323a0c78f61db1a3c5338045b0981850b (patch) | |
tree | 91eb409d2cc10b00840f8c783744fc1e3939c1ad /testsuite/tests/determinism | |
parent | fce758c5a5a54e8cfa491c5168893854bf7e974d (diff) | |
download | haskell-a5cb27f323a0c78f61db1a3c5338045b0981850b.tar.gz |
Make type-class dictionary let binds deterministic
When generating dictionary let binds in dsTcEvBinds we may
end up generating them in arbitrary order according to Unique order.
Consider:
```
let $dEq = GHC.Classes.$fEqInt in
let $$dNum = GHC.Num.$fNumInt in ...
```
vs
```
let $dNum = GHC.Num.$fNumInt in
let $dEq = GHC.Classes.$fEqInt in ...
```
The way this change fixes it is by using `UniqDFM` - a type of
deterministic finite maps of things keyed on `Unique`s. This way when
you pull out evidence variables corresponding to type-class dictionaries
they are in deterministic order.
Currently it's the order of insertion and the way it's implemented is by
tagging the values with the time of insertion.
Test Plan:
I've added a new test case to reproduce the issue.
./validate
Reviewers: ezyang, simonmar, austin, simonpj, bgamari
Reviewed By: simonmar, simonpj, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1396
GHC Trac Issues: #4012
Diffstat (limited to 'testsuite/tests/determinism')
-rw-r--r-- | testsuite/tests/determinism/determ003/A.hs | 22 | ||||
-rw-r--r-- | testsuite/tests/determinism/determ003/Makefile | 13 | ||||
-rw-r--r-- | testsuite/tests/determinism/determ003/all.T | 4 | ||||
-rw-r--r-- | testsuite/tests/determinism/determ003/determ003.stdout | 2 |
4 files changed, 41 insertions, 0 deletions
diff --git a/testsuite/tests/determinism/determ003/A.hs b/testsuite/tests/determinism/determ003/A.hs new file mode 100644 index 0000000000..fdfee7cc35 --- /dev/null +++ b/testsuite/tests/determinism/determ003/A.hs @@ -0,0 +1,22 @@ +module A () where + +-- This checks that the order of dictionary binds doesn't depend on the +-- order of Uniques. +-- Consider succ from Enum, it requires Num Int and Eq Int. The order of +-- let binds used to depend on the order of Uniques. Consider: +-- +-- let $dEq = GHC.Classes.$fEqInt in +-- let $$dNum = GHC.Num.$fNumInt in ... +-- +-- vs +-- +-- let $dNum = GHC.Num.$fNumInt in +-- let $dEq = GHC.Classes.$fEqInt in ... + +data B = C + deriving (Enum) + +f :: Int -> Int +f n + | n >= 0 = 0 + | otherwise = 0 diff --git a/testsuite/tests/determinism/determ003/Makefile b/testsuite/tests/determinism/determ003/Makefile new file mode 100644 index 0000000000..73231a0550 --- /dev/null +++ b/testsuite/tests/determinism/determ003/Makefile @@ -0,0 +1,13 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +TEST_HC_OPTS_NO_RECOMP = $(filter-out -fforce-recomp,$(TEST_HC_OPTS)) + +determ003: + $(RM) A.hi A.o + '$(TEST_HC)' $(TEST_HC_OPTS_NO_RECOMP) -O A.hs + $(CP) A.hi A.normal.hi + $(RM) A.hi A.o + '$(TEST_HC)' $(TEST_HC_OPTS_NO_RECOMP) -O -dinitial-unique=16777215 -dunique-increment=-1 A.hs + diff A.hi A.normal.hi diff --git a/testsuite/tests/determinism/determ003/all.T b/testsuite/tests/determinism/determ003/all.T new file mode 100644 index 0000000000..c00544d51a --- /dev/null +++ b/testsuite/tests/determinism/determ003/all.T @@ -0,0 +1,4 @@ +test('determ003', + extra_clean(['A.o', 'A.hi', 'A.normal.hi']), + run_command, + ['$MAKE -s --no-print-directory determ003']) diff --git a/testsuite/tests/determinism/determ003/determ003.stdout b/testsuite/tests/determinism/determ003/determ003.stdout new file mode 100644 index 0000000000..60c2bc368d --- /dev/null +++ b/testsuite/tests/determinism/determ003/determ003.stdout @@ -0,0 +1,2 @@ +[1 of 1] Compiling A ( A.hs, A.o ) +[1 of 1] Compiling A ( A.hs, A.o ) |