Audit shady uses of tcSplitSigmaTy
When fixing #12918 (closed), I ended up needing to introduce a helper function called tcSplitNestedSigmaTys
, which is quite similar to tcSplitSigmaTy
, except that it attempts to look through as many nested forall
s as possible. (See the documentation for tcSplitNestedSigmaTys
here).
In the process, I accidentally discovered a bug! First, consider this program:
{-# LANGUAGE RankNTypes #-}
module Bug where
class C a where
op :: forall b c. (Monoid b, Monoid c, Eq a) => a -> b -> c
This should be (and is) rejected, since we're trying to constrain a
with Eq
in op
, but we don't have -XConstraintedClassMethods
enabled. But what about this equivalent program?
{-# LANGUAGE RankNTypes #-}
module Bug where
class C a where
op :: forall b. Monoid b => forall c. Monoid c => Eq a => a -> b -> c
By the same logic, this should also be rejected. But in GHC 8.0.2, it wasn't! That's because we were checking for the presence of constrained class variables using tcSplitSigmaTy
, which only gives you Monoid b
as the constraint, totally ignoring the bogus constraint inside of forall c. Monoid c => Eq a => a -> b -> c
.
When I fixed #12918 (closed) (a seemingly unrelated task), I ended up replacing that very use of tcSplitSigmaTy
with tcSplitNestedSigmaTys
. Now it gives you (Monoid b, Monoid c, Eq a)
as expected when checking the constraints, and the second program is now rightly rejected on GHC HEAD.
But I fear that there may be many more bogus uses of tcSplitSigmaTy
. I should go through and try flushing out bugs of a similar caliber, and see if subbing in tcSplitNestedSigmaTys
fixes these bugs.
Trac metadata
Trac field | Value |
---|---|
Version | 8.1 |
Type | Task |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |