summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2018-09-23 15:23:09 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2018-09-26 04:36:28 +0100
commita74413479cf4bf84fcacf1c5f76da1c1610d208b (patch)
tree038d9bfd2b92b2cbe4f3c054ebc8a3c8c44987af
parent2a9ceadfa07e2298ce934c6d304a3ba1f529ad93 (diff)
downloadhaskell-a74413479cf4bf84fcacf1c5f76da1c1610d208b.tar.gz
Expand the Note on let-bound skolems
-rw-r--r--compiler/typecheck/TcSMonad.hs25
1 files changed, 25 insertions, 0 deletions
diff --git a/compiler/typecheck/TcSMonad.hs b/compiler/typecheck/TcSMonad.hs
index db29f67f86..3e50569633 100644
--- a/compiler/typecheck/TcSMonad.hs
+++ b/compiler/typecheck/TcSMonad.hs
@@ -2215,6 +2215,31 @@ For an example, see Trac #9211.
See also TcUnify Note [Deeper level on the left] for how we ensure
that the right variable is on the left of the equality when both are
tyvars.
+
+You might wonder whether the skokem really needs to be bound "in the
+very same implication" as the equuality constraint.
+(c.f. Trac #15009) Consider this:
+
+ data S a where
+ MkS :: (a ~ Int) => S a
+
+ g :: forall a. S a -> a -> blah
+ g x y = let h = \z. ( z :: Int
+ , case x of
+ MkS -> [y,z])
+ in ...
+
+From the type signature for `g`, we get `y::a` . Then when when we
+encounter the `\z`, we'll assign `z :: alpha[1]`, say. Next, from the
+body of the lambda we'll get
+
+ [W] alpha[1] ~ Int -- From z::Int
+ [W] forall[2]. (a ~ Int) => [W] alpha[1] ~ a -- From [y,z]
+
+Now, suppose we decide to float `alpha ~ a` out of the implication
+and then unify `alpha := a`. Now we are stuck! But if treat
+`alpha ~ Int` first, and unify `alpha := Int`, all is fine.
+But we absolutely cannot float that equality or we will get stuck.
-}
removeInertCts :: [Ct] -> InertCans -> InertCans