Adjust error check for class method types
authorSimon Peyton Jones <simonpj@microsoft.com>
Fri, 15 Apr 2016 10:49:23 +0000 (11:49 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Fri, 15 Apr 2016 11:48:28 +0000 (12:48 +0100)
Fixes Trac #11793.  Nothing deep here.

compiler/typecheck/TcTyClsDecls.hs
testsuite/tests/typecheck/should_compile/T11793.hs [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/all.T

index 7ad7bb4..1325966 100644 (file)
@@ -2377,9 +2377,12 @@ checkValidClass cls
           (_,theta2,_)    = tcSplitSigmaTy tau1
 
           check_constraint :: TcPredType -> TcM ()
-          check_constraint pred
-            = when (tyCoVarsOfType pred `subVarSet` cls_tv_set)
+          check_constraint pred -- See Note [Class method constraints]
+            = when (not (isEmptyVarSet pred_tvs) &&
+                    pred_tvs `subVarSet` cls_tv_set)
                    (addErrTc (badMethPred sel_id pred))
+            where
+              pred_tvs = tyCoVarsOfType pred
 
     check_at (ATI fam_tc m_dflt_rhs)
       = do { checkTc (cls_arity == 0 || any (`elemVarSet` cls_tv_set) fam_tvs)
@@ -2420,7 +2423,21 @@ checkFamFlag tc_name
     err_msg = hang (text "Illegal family declaration for" <+> quotes (ppr tc_name))
                  2 (text "Use TypeFamilies to allow indexed type families")
 
-{-
+{- Note [Class method constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Haskell 2010 is supposed to reject
+  class C a where
+    op :: Eq a => a -> a
+where the method type costrains only the class variable(s).  (The extension
+-XConstrainedClassMethods switches off this check.)  But regardless
+we should not reject
+  class C a where
+    op :: (?x::Int) => a -> a
+as pointed out in Trac #11793. So the test here rejects the program if
+  * -XConstrainedClassMethods is off
+  * the tyvars of the constraint are non-empty
+  * all the tyvars are class tyvars, none are locally quantified
+
 Note [Abort when superclass cycle is detected]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 We must avoid doing the ambiguity check for the methods (in
diff --git a/testsuite/tests/typecheck/should_compile/T11793.hs b/testsuite/tests/typecheck/should_compile/T11793.hs
new file mode 100644 (file)
index 0000000..f42a623
--- /dev/null
@@ -0,0 +1,8 @@
+{-# LANGUAGE ImplicitParams #-}
+
+module T11793 where
+
+class C a where
+  op :: (?x::Int) => a -> a
+
+-- Should be OK even without ConstrainedClassMethods
index bd973f1..8046fa3 100644 (file)
@@ -512,3 +512,4 @@ test('T11699', normal, compile, [''])
 test('T11512', normal, compile, [''])
 test('T11754', normal, compile, [''])
 test('T11811', normal, compile, [''])
+test('T11793', normal, compile, [''])