summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Solver/Monad.hs
diff options
context:
space:
mode:
authorRichard Eisenberg <rae@richarde.dev>2021-11-22 17:34:32 -0500
committerSimon Peyton Jones <simon.peytonjones@gmail.com>2023-01-11 08:30:42 +0000
commitaed1974e92366ab8e117734f308505684f70cddf (patch)
treebbfe7fdd00f1e0ef8dacdcf8d070a07efa38561b /compiler/GHC/Tc/Solver/Monad.hs
parent083f701553852c4460159cd6deb2515d3373714d (diff)
downloadhaskell-wip/T20666.tar.gz
Refactor the treatment of loopy superclass dictswip/T20666
This patch completely re-engineers how we deal with loopy superclass dictionaries in instance declarations. It fixes #20666 and #19690 The highlights are * Recognise that the loopy-superclass business should use precisely the Paterson conditions. This is much much nicer. See Note [Recursive superclasses] in GHC.Tc.TyCl.Instance * With that in mind, define "Paterson-smaller" in Note [Paterson conditions] in GHC.Tc.Validity, and the new data type `PatersonSize` in GHC.Tc.Utils.TcType, along with functions to compute and compare PatsonSizes * Use the new PatersonSize stuff when solving superclass constraints See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance * In GHC.Tc.Solver.Monad.lookupInInerts, add a missing call to prohibitedSuperClassSolve. This was the original cause of #20666. * Treat (TypeError "stuff") as having PatersonSize zero. See Note [Paterson size for type family applications] in GHC.Tc.Utils.TcType. * Treat the head of a Wanted quantified constraint in the same way as the superclass of an instance decl; this is what fixes #19690. See GHC.Tc.Solver.Canonical Note [Solving a Wanted forall-constraint] (Thanks to Matthew Craven for this insight.) This entailed refactoring the GivenSc constructor of CtOrigin a bit, to say whether it comes from an instance decl or quantified constraint. * Some refactoring way in which redundant constraints are reported; we don't want to complain about the extra, apparently-redundant constraints that we must add to an instance decl because of the loopy-superclass thing. I moved some work from GHC.Tc.Errors to GHC.Tc.Solver. * Add a new section to the user manual to describe the loopy superclass issue and what rules it follows.
Diffstat (limited to 'compiler/GHC/Tc/Solver/Monad.hs')
-rw-r--r--compiler/GHC/Tc/Solver/Monad.hs18
1 files changed, 15 insertions, 3 deletions
diff --git a/compiler/GHC/Tc/Solver/Monad.hs b/compiler/GHC/Tc/Solver/Monad.hs
index 67c90dcd80..b5cf81ad9d 100644
--- a/compiler/GHC/Tc/Solver/Monad.hs
+++ b/compiler/GHC/Tc/Solver/Monad.hs
@@ -672,8 +672,16 @@ lookupInInerts :: CtLoc -> TcPredType -> TcS (Maybe CtEvidence)
lookupInInerts loc pty
| ClassPred cls tys <- classifyPredType pty
= do { inerts <- getTcSInerts
- ; return (lookupSolvedDict inerts loc cls tys `mplus`
- fmap ctEvidence (lookupInertDict (inert_cans inerts) loc cls tys)) }
+ ; return $ -- Maybe monad
+ do { found_ev <-
+ lookupSolvedDict inerts loc cls tys `mplus`
+ fmap ctEvidence (lookupInertDict (inert_cans inerts) loc cls tys)
+ ; guard (not (prohibitedSuperClassSolve (ctEvLoc found_ev) loc))
+ -- We're about to "solve" the wanted we're looking up, so we
+ -- must make sure doing so wouldn't run afoul of
+ -- Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance.
+ -- Forgetting this led to #20666.
+ ; return found_ev }}
| otherwise -- NB: No caching for equalities, IPs, holes, or errors
= return Nothing
@@ -783,7 +791,11 @@ data TcSEnv
}
---------------
-newtype TcS a = TcS { unTcS :: TcSEnv -> TcM a } deriving (Functor)
+newtype TcS a = TcS { unTcS :: TcSEnv -> TcM a }
+ deriving (Functor)
+
+instance MonadFix TcS where
+ mfix k = TcS $ \env -> mfix (\x -> unTcS (k x) env)
-- | Smart constructor for 'TcS', as describe in Note [The one-shot state
-- monad trick] in "GHC.Utils.Monad".