summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2011-05-04 13:27:12 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2011-05-04 13:27:12 +0100
commita10a21dadac041e928ad5dab3810b68ab35bc9bb (patch)
treec51298b42fa17a5455c5195edd53408fc3b28e29
parent5096055e9aa46a7cc8b5a1292f7094fe588ec4d1 (diff)
downloadhaskell-a10a21dadac041e928ad5dab3810b68ab35bc9bb.tar.gz
Be cleverer in dataConCannotMatch, fixes Trac #5168
-rw-r--r--compiler/basicTypes/DataCon.lhs11
-rw-r--r--compiler/types/Unify.lhs7
2 files changed, 9 insertions, 9 deletions
diff --git a/compiler/basicTypes/DataCon.lhs b/compiler/basicTypes/DataCon.lhs
index 5e359848e2..458bfd3f81 100644
--- a/compiler/basicTypes/DataCon.lhs
+++ b/compiler/basicTypes/DataCon.lhs
@@ -835,16 +835,17 @@ dataConCannotMatch :: [Type] -> DataCon -> Bool
-- Returns True iff the data con *definitely cannot* match a
-- scrutinee of type (T tys)
-- where T is the type constructor for the data con
---
+-- NB: look at *all* equality constraints, not only those
+-- in dataConEqSpec; see Trac #5168
dataConCannotMatch tys con
- | null eq_spec = False -- Common
+ | null theta = False -- Common
| all isTyVarTy tys = False -- Also common
| otherwise
- = typesCantMatch (map (substTyVar subst . fst) eq_spec)
- (map snd eq_spec)
+ = typesCantMatch [(Type.substTy subst ty1, Type.substTy subst ty2)
+ | EqPred ty1 ty2 <- theta ]
where
dc_tvs = dataConUnivTyVars con
- eq_spec = dataConEqSpec con
+ theta = dataConTheta con
subst = zipTopTvSubst dc_tvs tys
\end{code}
diff --git a/compiler/types/Unify.lhs b/compiler/types/Unify.lhs
index 38507830ab..9c448ce065 100644
--- a/compiler/types/Unify.lhs
+++ b/compiler/types/Unify.lhs
@@ -316,9 +316,8 @@ anything, type functions (incl newtypes) match anything, and only
distinct data types fail to match. We can elaborate later.
\begin{code}
-typesCantMatch :: [Type] -> [Type] -> Bool
-typesCantMatch tys1 tys2 = ASSERT( equalLength tys1 tys2 )
- or (zipWith cant_match tys1 tys2)
+typesCantMatch :: [(Type,Type)] -> Bool
+typesCantMatch prs = any (\(s,t) -> cant_match s t) prs
where
cant_match :: Type -> Type -> Bool
cant_match t1 t2
@@ -330,7 +329,7 @@ typesCantMatch tys1 tys2 = ASSERT( equalLength tys1 tys2 )
cant_match (TyConApp tc1 tys1) (TyConApp tc2 tys2)
| isDataTyCon tc1 && isDataTyCon tc2
- = tc1 /= tc2 || typesCantMatch tys1 tys2
+ = tc1 /= tc2 || typesCantMatch (zipEqual "typesCantMatch" tys1 tys2)
cant_match (FunTy {}) (TyConApp tc _) = isDataTyCon tc
cant_match (TyConApp tc _) (FunTy {}) = isDataTyCon tc