summaryrefslogtreecommitdiff
path: root/compiler/typecheck/TcValidity.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/typecheck/TcValidity.hs')
-rw-r--r--compiler/typecheck/TcValidity.hs27
1 files changed, 20 insertions, 7 deletions
diff --git a/compiler/typecheck/TcValidity.hs b/compiler/typecheck/TcValidity.hs
index f9e7831d9a..927690c796 100644
--- a/compiler/typecheck/TcValidity.hs
+++ b/compiler/typecheck/TcValidity.hs
@@ -442,7 +442,7 @@ rankZeroMonoType = MonoType (text "Perhaps you intended to use RankNTypes or R
tyConArgMonoType = MonoType (text "GHC doesn't yet support impredicative polymorphism")
synArgMonoType = MonoType (text "Perhaps you intended to use LiberalTypeSynonyms")
constraintMonoType = MonoType (vcat [ text "A constraint must be a monotype"
- , text "Perhpas you intended to use QuantifiedConstraints" ])
+ , text "Perhaps you intended to use QuantifiedConstraints" ])
funArgResRank :: Rank -> (Rank, Rank) -- Function argument and result
funArgResRank (LimitedRank _ arg_rank) = (arg_rank, LimitedRank (forAllAllowed arg_rank) arg_rank)
@@ -1409,6 +1409,7 @@ checkInstTermination theta head_pred
-> check2 foralld_tvs pred bogus_size
where
bogus_size = 1 + sizeTypes (filterOutInvisibleTypes (classTyCon cls) tys)
+ -- See Note [Invisible arguments and termination]
ForAllPred tvs theta pred
-> do { check (foralld_tvs `extendVarSetList` binderVars tvs) pred
@@ -1570,6 +1571,20 @@ Here the instance is kind-indexed and really looks like
type F (k->k) (b::k->k) = Int
But if the 'b' didn't scope, we would make F's instance too
poly-kinded.
+
+Note [Invisible arguments and termination]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When checking the ​Paterson conditions for termination an instance
+declaration, we check for the number of "constructors and variables"
+in the instance head and constraints. Question: Do we look at
+
+ * All the arguments, visible or invisible?
+ * Just the visible arguments?
+
+I think both will ensure termination, provided we are consistent.
+Currently we are /not/ consistent, which is really a bug. It's
+described in Trac #15177, which contains a number of examples.
+The suspicious bits are the calls to filterOutInvisibleTypes.
-}
-- | Extra information about the parent instance declaration, needed
@@ -2001,10 +2016,7 @@ sizeTypes = foldr ((+) . sizeType) 0
sizeTyConAppArgs :: TyCon -> [Type] -> Int
sizeTyConAppArgs _tc tys = sizeTypes tys -- (filterOutInvisibleTypes tc tys)
-
--- instance (Category w, Prelude.Monad m) => Monad (WriterT w m) where
--- Category * w_auL
--- Monad (WriterT w_auL m_auM)
+ -- See Note [Invisible arguments and termination]
-- Size of a predicate
--
@@ -2020,10 +2032,11 @@ sizePred ty = goClass ty
go (ClassPred cls tys')
| isTerminatingClass cls = 0
| otherwise = sizeTypes (filterOutInvisibleTypes (classTyCon cls) tys')
- -- The filtering looks bogus: see Trac #15177
+ -- The filtering looks bogus
+ -- See Note [Invisible arguments and termination]
go (EqPred {}) = 0
go (IrredPred ty) = sizeType ty
- go (ForAllPred _ _ pred) = goClass pred -- Is this right?
+ go (ForAllPred _ _ pred) = goClass pred
-- | When this says "True", ignore this class constraint during
-- a termination check