summaryrefslogtreecommitdiff
path: root/testsuite/tests/typecheck/should_fail/tcfail157.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/typecheck/should_fail/tcfail157.hs')
-rw-r--r--testsuite/tests/typecheck/should_fail/tcfail157.hs39
1 files changed, 39 insertions, 0 deletions
diff --git a/testsuite/tests/typecheck/should_fail/tcfail157.hs b/testsuite/tests/typecheck/should_fail/tcfail157.hs
new file mode 100644
index 0000000000..74f02ed1e5
--- /dev/null
+++ b/testsuite/tests/typecheck/should_fail/tcfail157.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
+ FlexibleInstances #-}
+-- NB: *no* UndecidableInstances
+
+-- This one (due to Oleg) made 6.4.1 go into a loop in the typechecker,
+-- despite the lack of UndecidableInstances
+--
+-- The example corresponds to a type function (realized as a class E
+-- with functional dependencies) in the context of an instance.
+-- The function in question is
+--
+-- class E m a b | m a -> b
+-- instance E m (() -> ()) (m ())
+--
+-- We see that the result of the function, "m ()" is smaller (in the
+-- number of constructors) that the functions' arguments, "m" and
+-- "() -> ()" together. Plus any type variable free in the result is also
+-- free in at least one of the arguments. And yet it loops.
+module ShouldFail where
+
+class Foo m a where
+ foo :: m b -> a -> Bool
+
+instance Foo m () where
+ foo _ _ = True
+
+instance (E m a b, Foo m b) => Foo m (a->()) where
+ foo m f = undefined
+
+class E m a b | m a -> b where
+ tr :: m c -> a -> b
+
+-- There is only one instance of the class with functional dependencies
+instance E m (() -> ()) (m ()) where
+ tr x = undefined
+
+-- GHC(i) loops
+
+test = foo (\f -> (f ()) :: ()) (\f -> (f ()) :: ())