diff options
author | simonpj@microsoft.com <unknown> | 2011-02-17 14:10:00 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2011-02-17 14:10:00 +0000 |
commit | a6c8ac78466af399df1372aa4f9271be32e73fcd (patch) | |
tree | 6851eb1e0a40c45d6a6474b9899b80d106fb5b3b /compiler | |
parent | 50d0293555691012f96259de7f8682b94db58517 (diff) | |
download | haskell-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.lhs | 35 |
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 |