summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorsimonpj@microsoft.com <unknown>2011-02-17 14:10:00 +0000
committersimonpj@microsoft.com <unknown>2011-02-17 14:10:00 +0000
commita6c8ac78466af399df1372aa4f9271be32e73fcd (patch)
tree6851eb1e0a40c45d6a6474b9899b80d106fb5b3b /compiler
parent50d0293555691012f96259de7f8682b94db58517 (diff)
downloadhaskell-a6c8ac78466af399df1372aa4f9271be32e73fcd.tar.gz
Fix Trac #4966
This is just a program that exploits overlapping instances in a delicate way. The fix makes GHC a bit more friendly towards such programs. See Note [Overlap and deriving] in TcSimplify
Diffstat (limited to 'compiler')
-rw-r--r--compiler/typecheck/TcSimplify.lhs35
1 files changed, 30 insertions, 5 deletions
diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs
index 0a4fe07336..ccdadeedaa 100644
--- a/compiler/typecheck/TcSimplify.lhs
+++ b/compiler/typecheck/TcSimplify.lhs
@@ -82,11 +82,11 @@ simplifyDeriv :: CtOrigin
-- Simplify 'wanted' as much as possibles
-- Fail if not possible
simplifyDeriv orig tvs theta
- = do { tvs_skols <- tcInstSuperSkolTyVars tvs -- Skolemize
- -- One reason is that the constraint solving machinery
- -- expects *TcTyVars* not TyVars. Another is that
- -- when looking up instances we don't want overlap
- -- of type variables
+ = do { tvs_skols <- tcInstSkolTyVars tvs -- Skolemize
+ -- The constraint solving machinery
+ -- expects *TcTyVars* not TyVars.
+ -- We use *non-overlappable* (vanilla) skolems
+ -- See Note [Overlap and deriving]
; let skol_subst = zipTopTvSubst tvs $ map mkTyVarTy tvs_skols
subst_skol = zipTopTvSubst tvs_skols $ map mkTyVarTy tvs
@@ -111,6 +111,31 @@ simplifyDeriv orig tvs theta
; return (substTheta subst_skol min_theta) }
\end{code}
+Note [Overlap and deriving]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider some overlapping instances:
+ data Show a => Show [a] where ..
+ data Show [Char] where ...
+
+Now a data type with deriving:
+ data T a = MkT [a] deriving( Show )
+
+We want to get the derived instance
+ instance Show [a] => Show (T a) where...
+and NOT
+ instance Show a => Show (T a) where...
+so that the (Show (T Char)) instance does the Right Thing
+
+It's very like the situation when we're inferring the type
+of a function
+ f x = show [x]
+and we want to infer
+ f :: Show [a] => a -> String
+
+BOTTOM LINE: use vanilla, non-overlappable skolems when inferring
+ the context for the derived instance.
+ Hence tcInstSkolTyVars not tcInstSuperSkolTyVars
+
Note [Exotic derived instance contexts]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In a 'derived' instance declaration, we *infer* the context. It's a