summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Nitka <niteria@gmail.com>2016-06-29 03:27:49 -0700
committerBartosz Nitka <niteria@gmail.com>2016-06-29 05:54:58 -0700
commit9a645a1687aca21f965206f1d8c8bb23dd6410e5 (patch)
tree54235cd3127ce5a9ab17fbb112fbf7acf4d8d039
parent848e3ceb881ef5a5bbfe23965b75d22f96a21229 (diff)
downloadhaskell-9a645a1687aca21f965206f1d8c8bb23dd6410e5.tar.gz
Refactor match to not use Unique order
Unique order can introduce nondeterminism. As a step towards removing the Ord Unique instance I've refactored the code to use deterministic sets instead. Test Plan: ./validate Reviewers: simonmar, austin, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2369 GHC Trac Issues: #4012
-rw-r--r--compiler/deSugar/Match.hs32
1 files changed, 23 insertions, 9 deletions
diff --git a/compiler/deSugar/Match.hs b/compiler/deSugar/Match.hs
index fc70cc643d..ecbed46185 100644
--- a/compiler/deSugar/Match.hs
+++ b/compiler/deSugar/Match.hs
@@ -46,6 +46,8 @@ import Util
import Name
import Outputable
import BasicTypes ( isGenerated )
+import Unique
+import UniqDFM
import Control.Monad( when, unless )
import qualified Data.Map as Map
@@ -196,9 +198,9 @@ match vars@(v:_) ty eqns -- Eqns *can* be empty
match_group [] = panic "match_group"
match_group eqns@((group,_) : _)
= case group of
- PgCon {} -> matchConFamily vars ty (subGroup [(c,e) | (PgCon c, e) <- eqns])
+ PgCon {} -> matchConFamily vars ty (subGroupUniq [(c,e) | (PgCon c, e) <- eqns])
PgSyn {} -> matchPatSyn vars ty (dropGroup eqns)
- PgLit {} -> matchLiterals vars ty (subGroup [(l,e) | (PgLit l, e) <- eqns])
+ PgLit {} -> matchLiterals vars ty (subGroupOrd [(l,e) | (PgLit l, e) <- eqns])
PgAny -> matchVariables vars ty (dropGroup eqns)
PgN {} -> matchNPats vars ty (dropGroup eqns)
PgNpK {} -> matchNPlusKPats vars ty (dropGroup eqns)
@@ -809,22 +811,34 @@ groupEquations dflags eqns
same_gp :: (PatGroup,EquationInfo) -> (PatGroup,EquationInfo) -> Bool
(pg1,_) `same_gp` (pg2,_) = pg1 `sameGroup` pg2
-subGroup :: Ord a => [(a, EquationInfo)] -> [[EquationInfo]]
+subGroup :: (m -> [[EquationInfo]]) -- Map.elems
+ -> m -- Map.empty
+ -> (a -> m -> Maybe [EquationInfo]) -- Map.lookup
+ -> (a -> [EquationInfo] -> m -> m) -- Map.insert
+ -> [(a, EquationInfo)] -> [[EquationInfo]]
-- Input is a particular group. The result sub-groups the
-- equations by with particular constructor, literal etc they match.
-- Each sub-list in the result has the same PatGroup
-- See Note [Take care with pattern order]
-subGroup group
- = map reverse $ Map.elems $ foldl accumulate Map.empty group
+-- Parameterized by map operations to allow different implementations
+-- and constraints, eg. types without Ord instance.
+subGroup elems empty lookup insert group
+ = map reverse $ elems $ foldl accumulate empty group
where
accumulate pg_map (pg, eqn)
- = case Map.lookup pg pg_map of
- Just eqns -> Map.insert pg (eqn:eqns) pg_map
- Nothing -> Map.insert pg [eqn] pg_map
-
+ = case lookup pg pg_map of
+ Just eqns -> insert pg (eqn:eqns) pg_map
+ Nothing -> insert pg [eqn] pg_map
-- pg_map :: Map a [EquationInfo]
-- Equations seen so far in reverse order of appearance
+subGroupOrd :: Ord a => [(a, EquationInfo)] -> [[EquationInfo]]
+subGroupOrd = subGroup Map.elems Map.empty Map.lookup Map.insert
+
+subGroupUniq :: Uniquable a => [(a, EquationInfo)] -> [[EquationInfo]]
+subGroupUniq =
+ subGroup eltsUDFM emptyUDFM (flip lookupUDFM) (\k v m -> addToUDFM m k v)
+
{- Note [Pattern synonym groups]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we see