summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Errors
diff options
context:
space:
mode:
authorRichard Eisenberg <rae@richarde.dev>2020-04-29 17:14:53 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-05-06 04:39:32 -0400
commit7ab6ab093c86227b6d33a5185ebbd11928ac9754 (patch)
tree9012ba8808f2e7d5271d2d8a225c2223f4ba6aa2 /compiler/GHC/Tc/Errors
parent40c71c2cf38b4e134d81b7184a4d5e02949ae70c (diff)
downloadhaskell-7ab6ab093c86227b6d33a5185ebbd11928ac9754.tar.gz
Refactor hole constraints.
Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG -------------------------
Diffstat (limited to 'compiler/GHC/Tc/Errors')
-rw-r--r--compiler/GHC/Tc/Errors/Hole.hs195
-rw-r--r--compiler/GHC/Tc/Errors/Hole.hs-boot4
-rw-r--r--compiler/GHC/Tc/Errors/Hole/FitTypes.hs26
3 files changed, 93 insertions, 132 deletions
diff --git a/compiler/GHC/Tc/Errors/Hole.hs b/compiler/GHC/Tc/Errors/Hole.hs
index 543fa0fca0..7cbd8dbc0b 100644
--- a/compiler/GHC/Tc/Errors/Hole.hs
+++ b/compiler/GHC/Tc/Errors/Hole.hs
@@ -2,17 +2,9 @@
{-# LANGUAGE ExistentialQuantification #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
module GHC.Tc.Errors.Hole
- ( findValidHoleFits, tcFilterHoleFits
- , tcCheckHoleFit, tcSubsumes
- , withoutUnification
- , fromPureHFPlugin
- -- Re-exports for convenience
- , hfIsLcl
- , pprHoleFit, debugHoleFitDispConfig
+ ( findValidHoleFits
-- Re-exported from GHC.Tc.Errors.Hole.FitTypes
- , TypedHole (..), HoleFit (..), HoleFitCandidate (..)
- , CandPlugin, FitPlugin
, HoleFitPlugin (..), HoleFitPluginR (..)
)
where
@@ -121,7 +113,7 @@ The hole in `f` would generate the message:
Valid hole fits are found by checking top level identifiers and local bindings
in scope for whether their type can be instantiated to the the type of the hole.
Additionally, we also need to check whether all relevant constraints are solved
-by choosing an identifier of that type as well, see Note [Relevant Constraints]
+by choosing an identifier of that type as well, see Note [Relevant constraints]
Since checking for subsumption results in the side-effect of type variables
being unified by the simplifier, we need to take care to restore them after
@@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like
If -XTypeApplications is enabled, this can even be copied verbatim as a
replacement for the hole.
-
-Note [Nested implications]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [Checking hole fits]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+If we have a hole of type hole_ty, we want to know whether a variable
+of type ty is a valid fit for the whole. This is a subsumption check:
+we wish to know whether ty <: hole_ty. But, of course, the check
+must take into account any givens and relevant constraints.
+(See also Note [Relevant constraints]).
For the simplifier to be able to use any givens present in the enclosing
implications to solve relevant constraints, we nest the wanted subsumption
@@ -156,10 +152,7 @@ As an example, let's look at the following code:
f :: Show a => a -> String
f x = show _
-The hole will result in the hole constraint:
-
- [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_))
-
+Suppose the hole is assigned type a0_a1pd[tau:2].
Here the nested implications are just one level deep, namely:
[Implic {
@@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely:
Given = $dShow_a1pc :: Show a_a1pa[sk:2]
Wanted =
WC {wc_simple =
- [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_))
- [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))}
+ [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))}
Binds = EvBindsVar<a1pi>
Needed inner = []
Needed outer = []
the type signature for:
f :: forall a. Show a => a -> String }]
-As we can see, the givens say that the information about the skolem
-`a_a1pa[sk:2]` fulfills the Show constraint.
-
-The simples are:
+As we can see, the givens say that the skolem
+`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove
+the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the
+hole must have a Show instance.
- [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)),
- [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)]
-
-I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must
-fulfill `Show a0_a1pd[tau:2])`.
-
-So when we run the check, we need to make sure that the
-
- [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)
-
-Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits
-the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the
-meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted
-constraints needed by tcSubType_NC and the relevant constraints (see
-Note [Relevant Constraints] for more details) in the nested implications, we
-can pass the information in the givens along to the simplifier. For our example,
-we end up needing to check whether the following constraints are soluble.
+When we now check whether `x :: a_a1pa[sk:2]` fits the hole in
+`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type
+variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints
+needed by tcSubType_NC and the relevant constraints (see Note [Relevant
+Constraints] for more details) in the nested implications, we can pass the
+information in the givens along to the simplifier. For our example, we end up
+needing to check whether the following constraints are soluble.
WC {wc_impl =
Implic {
@@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match.
To avoid side-effects on the nested implications, we create a new EvBindsVar so
that any changes to the ev binds during a check remains localised to that check.
-
+In addition, we call withoutUnification to reset any unified metavariables; this
+call is actually done outside tcCheckHoleFit so that the results can be formatted
+for the user before resetting variables.
Note [Valid refinement hole fits include ...]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When the `-frefinement-level-hole-fits=N` flag is given, we additionally look
for "valid refinement hole fits"", i.e. valid hole fits with up to N
additional holes in them.
@@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with
be applied to an expression of type `a -> Free f b` in order to match.
If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim.
-
-Note [Relevant Constraints]
-~~~~~~~~~~~~~~~~~~~
-
+Note [Relevant constraints]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
As highlighted by #14273, we need to check any relevant constraints as well
as checking for subsumption. Relevant constraints are the simple constraints
whose free unification variables are mentioned in the type of the hole.
@@ -351,10 +333,9 @@ as is the case in
f :: String
f = show _
-Where the simples will be :
+Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is:
- [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)),
- [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)]
+ [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)
However, when there are multiple holes, we need to be more careful. As an
example, Let's take a look at the following code:
@@ -362,29 +343,24 @@ example, Let's take a look at the following code:
f :: Show a => a -> String
f x = show (_b (show _a))
-Here there are two holes, `_a` and `_b`, and the simple constraints passed to
+Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and
+_b :: a1_a1po[tau:2]. Then, the simple constraints passed to
findValidHoleFits are:
- [[WD] _a_a1pi {0}:: String
- -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)),
- [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)),
- [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical),
+ [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical),
[WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)]
-
-Here we have the two hole constraints for `_a` and `_b`, but also additional
-constraints that these holes must fulfill. When we are looking for a match for
-the hole `_a`, we filter the simple constraints to the "Relevant constraints",
-by throwing out all hole constraints and any constraints which do not mention
-a variable mentioned in the type of the hole. For hole `_a`, we will then
-only require that the `$dShow_a1pp` constraint is solved, since that is
-the only non-hole constraint that mentions any free type variables mentioned in
-the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the
-hole `_b` we only require that the `$dShow_a1pe` constraint is solved.
+When we are looking for a match for the hole `_a`, we filter the simple
+constraints to the "Relevant constraints", by throwing out any constraints
+which do not mention a variable mentioned in the type of the hole. For hole
+`_a`, we will then only require that the `$dShow_a1pe` constraint is solved,
+since that is the only constraint that mentions any free type variables
+mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and
+similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint
+is solved.
Note [Leaking errors]
-~~~~~~~~~~~~~~~~~~~
-
+~~~~~~~~~~~~~~~~~~~~~
When considering candidates, GHC believes that we're checking for validity in
actual source. However, As evidenced by #15321, #15007 and #15202, this can
cause bewildering error messages. The solution here is simple: if a candidate
@@ -393,17 +369,12 @@ is discarded.
-}
-
data HoleFitDispConfig = HFDC { showWrap :: Bool
, showWrapVars :: Bool
, showType :: Bool
, showProv :: Bool
, showMatches :: Bool }
-debugHoleFitDispConfig :: HoleFitDispConfig
-debugHoleFitDispConfig = HFDC True True True False False
-
-
-- We read the various -no-show-*-of-hole-fits flags
-- and set the display config accordingly.
getHoleFitDispConfig :: TcM HoleFitDispConfig
@@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) =
GreHFCand gre -> pprNameProvenance gre
_ -> text "bound at" <+> ppr (getSrcLoc name)
-getLocalBindings :: TidyEnv -> Ct -> TcM [Id]
-getLocalBindings tidy_orig ct
- = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc)
+getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id]
+getLocalBindings tidy_orig ct_loc
+ = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc)
; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) }
where
- loc = ctEvLoc (ctEvidence ct)
- lcl_env = ctLocEnv loc
+ lcl_env = ctLocEnv ct_loc
go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id]
go _ sofar [] = return (reverse sofar)
@@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking
-> [Ct]
-- ^ The unsolved simple constraints in the implication for
-- the hole.
- -> Ct -- ^ The hole constraint itself
+ -> Hole
-> TcM (TidyEnv, SDoc)
-findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct =
+findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _
+ , hole_loc = ct_loc
+ , hole_ty = hole_ty }) =
do { rdr_env <- getGlobalRdrEnv
- ; lclBinds <- getLocalBindings tidy_env ct
+ ; lclBinds <- getLocalBindings tidy_env ct_loc
; maxVSubs <- maxValidHoleFits <$> getDynFlags
; hfdc <- getHoleFitDispConfig
; sortingAlg <- getSortingAlg
@@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct =
; hfPlugs <- tcg_hf_plugins <$> getGblEnv
; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs
refLevel = refLevelHoleFits dflags
- hole = TyH (listToBag relevantCts) implics (Just ct)
+ hole = TypedHole { th_relevant_cts = listToBag relevantCts
+ , th_implics = implics
+ , th_hole = Just h }
(candidatePlugins, fitPlugins) =
unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs
; traceTc "findingValidHoleFitsFor { " $ ppr hole
@@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct =
where
-- We extract the type, the tcLevel and the types free variables
-- from from the constraint.
- hole_ty :: TcPredType
- hole_ty = ctPred ct
hole_fvs :: FV
hole_fvs = tyCoFVsOfType hole_ty
- hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct
+ hole_lvl = ctLocLevel ct_loc
-- BuiltInSyntax names like (:) and []
builtIns :: [Name]
@@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct =
<*> sortByGraph (sort gblFits)
where (lclFits, gblFits) = span hfIsLcl subs
- -- See Note [Relevant Constraints]
+ -- See Note [Relevant constraints]
relevantCts :: [Ct]
relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then []
else filter isRelevant simples
@@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct =
-- trying to find hole fits for many holes at once.
isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct))
&& anyFVMentioned ct
- && not (isHoleCt ct)
-- We zonk the hole fits so that the output aligns with the rest
-- of the typed hole error message output.
@@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int
-- ^ We return whether or not we stopped due to hitting the limit
-- and the fits we found.
tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0
-tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates =
+tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates =
do { traceTc "checkingFitsFor {" $ ppr hole_ty
; (discards, subs) <- go [] emptyVarSet limit ht candidates
; traceTc "checkingFitsFor }" empty
@@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates =
else return Nothing }
else return Nothing }
where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty
- hole = TyH tyHRelevantCts tyHImplics Nothing
-
+ hole = typed_hole { th_hole = Nothing }
subsDiscardMsg :: SDoc
subsDiscardMsg =
@@ -925,7 +895,8 @@ withoutUnification free_vars action =
-- Reset any mutated free variables
; mapM_ restore flexis
; return result }
- where restore = flip writeTcRef Flexi . metaTyVarRef
+ where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv)
+ ; writeTcRef (metaTyVarRef tv) Flexi }
fuvs = fvVarList free_vars
-- | Reports whether first type (ty_a) subsumes the second type (ty_b),
@@ -933,14 +904,14 @@ withoutUnification free_vars action =
-- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a.
tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool
tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b
- where dummyHole = TyH emptyBag [] Nothing
+ where dummyHole = TypedHole { th_relevant_cts = emptyBag
+ , th_implics = []
+ , th_hole = Nothing }
-- | A tcSubsumes which takes into account relevant constraints, to fix trac
-- #14273. This makes sure that when checking whether a type fits the hole,
-- the type has to be subsumed by type of the hole as well as fulfill all
-- constraints on the type of the hole.
--- Note: The simplifier may perform unification, so make sure to restore any
--- free type variables to avoid side-effects.
tcCheckHoleFit :: TypedHole -- ^ The hole to check against
-> TcSigmaType
-- ^ The type to check against (possibly modified, e.g. refined)
@@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against
-- ^ Whether it was a match, and the wrapper from hole_ty to ty.
tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty
= return (True, idHsWrapper)
-tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $
+tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $
do { -- We wrap the subtype constraint in the implications to pass along the
-- givens, and so we must ensure that any nested implications and skolems
-- end up with the correct level. The implications are ordered so that
-- the innermost (the one with the highest level) is first, so it
-- suffices to get the level of the first one (or the current level, if
-- there are no implications involved).
- innermost_lvl <- case tyHImplics of
+ innermost_lvl <- case th_implics of
[] -> getTcLevel
-- imp is the innermost implication
(imp:_) -> return (ic_tclvl imp)
- ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $
- tcSubType_NC ExprSigCtxt ty hole_ty
+ ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $
+ tcSubType_NC ExprSigCtxt ty hole_ty
; traceTc "Checking hole fit {" empty
; traceTc "wanteds are: " $ ppr wanted
- ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts
- then traceTc "}" empty >> return (True, wrp)
+ ; if isEmptyWC wanted && isEmptyBag th_relevant_cts
+ then do { traceTc "}" empty
+ ; return (True, wrap) }
else do { fresh_binds <- newTcEvBinds
-- The relevant constraints may contain HoleDests, so we must
-- take care to clone them as well (to avoid #15370).
- ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts
+ ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts
-- We wrap the WC in the nested implications, see
- -- Note [Nested Implications]
- ; let outermost_first = reverse tyHImplics
- setWC = setWCAndBinds fresh_binds
+ -- Note [Checking hole fits]
+ ; let outermost_first = reverse th_implics
-- We add the cloned relevants to the wanteds generated by
- -- the call to tcSubType_NC, see Note [Relevant Constraints]
+ -- the call to tcSubType_NC, see Note [Relevant constraints]
-- There's no need to clone the wanteds, because they are
-- freshly generated by `tcSubtype_NC`.
w_rel_cts = addSimples wanted cloned_relevants
- w_givens = foldr setWC w_rel_cts outermost_first
- ; traceTc "w_givens are: " $ ppr w_givens
- ; rem <- runTcSDeriveds $ simpl_top w_givens
+ final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first
+ ; traceTc "final_wc is: " $ ppr final_wc
+ ; rem <- runTcSDeriveds $ simpl_top final_wc
-- We don't want any insoluble or simple constraints left, but
-- solved implications are ok (and necessary for e.g. undefined)
; traceTc "rems was:" $ ppr rem
; traceTc "}" empty
- ; return (isSolvedWC rem, wrp) } }
+ ; return (isSolvedWC rem, wrap) } }
where
setWCAndBinds :: EvBindsVar -- Fresh ev binds var.
-> Implication -- The implication to put WC in.
-> WantedConstraints -- The WC constraints to put implic.
-> WantedConstraints -- The new constraints.
setWCAndBinds binds imp wc
- = WC { wc_simple = emptyBag
- , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } }
-
--- | Maps a plugin that needs no state to one with an empty one.
-fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR
-fromPureHFPlugin plug =
- HoleFitPluginR { hfPluginInit = newTcRef ()
- , hfPluginRun = const plug
- , hfPluginStop = const $ return () }
+ = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds }
diff --git a/compiler/GHC/Tc/Errors/Hole.hs-boot b/compiler/GHC/Tc/Errors/Hole.hs-boot
index fa3299c5d3..215f319c79 100644
--- a/compiler/GHC/Tc/Errors/Hole.hs-boot
+++ b/compiler/GHC/Tc/Errors/Hole.hs-boot
@@ -5,9 +5,9 @@
module GHC.Tc.Errors.Hole where
import GHC.Tc.Types ( TcM )
-import GHC.Tc.Types.Constraint ( Ct, Implication )
+import GHC.Tc.Types.Constraint ( Ct, Hole, Implication )
import GHC.Utils.Outputable ( SDoc )
import GHC.Types.Var.Env ( TidyEnv )
-findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct
+findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole
-> TcM (TidyEnv, SDoc)
diff --git a/compiler/GHC/Tc/Errors/Hole/FitTypes.hs b/compiler/GHC/Tc/Errors/Hole/FitTypes.hs
index 92bbe00115..23943a8617 100644
--- a/compiler/GHC/Tc/Errors/Hole/FitTypes.hs
+++ b/compiler/GHC/Tc/Errors/Hole/FitTypes.hs
@@ -21,20 +21,21 @@ import GHC.Types.Name
import Data.Function ( on )
-data TypedHole = TyH { tyHRelevantCts :: Cts
- -- ^ Any relevant Cts to the hole
- , tyHImplics :: [Implication]
- -- ^ The nested implications of the hole with the
- -- innermost implication first.
- , tyHCt :: Maybe Ct
- -- ^ The hole constraint itself, if available.
- }
+data TypedHole = TypedHole { th_relevant_cts :: Cts
+ -- ^ Any relevant Cts to the hole
+ , th_implics :: [Implication]
+ -- ^ The nested implications of the hole with the
+ -- innermost implication first.
+ , th_hole :: Maybe Hole
+ -- ^ The hole itself, if available. Only for debugging.
+ }
instance Outputable TypedHole where
- ppr (TyH rels implics ct)
+ ppr (TypedHole { th_relevant_cts = rels
+ , th_implics = implics
+ , th_hole = hole })
= hang (text "TypedHole") 2
- (ppr rels $+$ ppr implics $+$ ppr ct)
-
+ (ppr rels $+$ ppr implics $+$ ppr hole)
-- | HoleFitCandidates are passed to hole fit plugins and then
-- checked whether they fit a given typed-hole.
@@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid
pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname
pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre
-
-
-
instance NamedThing HoleFitCandidate where
getName hfc = case hfc of
IdHFCand cid -> idName cid