Simon Peyton Jones pushed to branch wip/T26315 at Glasgow Haskell Compiler / GHC
Commits:
-
6a93a288
by Simon Peyton Jones at 2025-09-04T13:08:04+01:00
8 changed files:
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Types/Evidence.hs
Changes:
... | ... | @@ -741,7 +741,7 @@ Note that |
741 | 741 | the same (Eq p) dictionary. Reason: we don't want to force them to be visibly
|
742 | 742 | equal at the call site.
|
743 | 743 | |
744 | -* The `spec_bnrs`, which are lambda-bound in the specialised function `$sf`,
|
|
744 | +* The `spec_bndrs`, which are lambda-bound in the specialised function `$sf`,
|
|
745 | 745 | are a subset of `rule_bndrs`.
|
746 | 746 | |
747 | 747 | spec_bndrs = @p (d2::Eq p) (x::Int) (y::p)
|
... | ... | @@ -759,7 +759,8 @@ This is done in three parts. |
759 | 759 | |
760 | 760 | (1) Typecheck the expression, capturing its constraints
|
761 | 761 | |
762 | - (2) Solve these constraints
|
|
762 | + (2) Solve these constraints. When doing so, switch on `tcsmFullySolveQCIs`;
|
|
763 | + see wrinkle (NFS1) below.
|
|
763 | 764 | |
764 | 765 | (3) Compute the constraints to quantify over, using `getRuleQuantCts` on
|
765 | 766 | the unsolved constraints returned by (2).
|
... | ... | @@ -795,6 +796,28 @@ This is done in three parts. |
795 | 796 | of the form:
|
796 | 797 | forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3
|
797 | 798 | |
799 | +(NFS1) Consider
|
|
800 | + f :: forall f a. (Ix a, forall x. Eq x => Eq (f x)) => a -> f a
|
|
801 | + {-# SPECIALISE f :: forall f. (forall x. Eq x => Eq (f x)) => Int -> f Int #-}
|
|
802 | + This SPECIALISE is treated like an expression with a type signature, so
|
|
803 | + we instantiate the constraints, simplify them and re-generalise. From the
|
|
804 | + instantiation we get [W] d :: (forall x. Eq a => Eq (f x))
|
|
805 | + and we want to generalise over that. We do not want to attempt to solve it
|
|
806 | + and then get stuck, and emit an error message. If we can't solve it, it is
|
|
807 | + much, much better to leave it alone.
|
|
808 | + |
|
809 | + We still need to simplify quantified constraints that can be /fully solved/
|
|
810 | + from instances, otherwise we would never be able to specialise them
|
|
811 | + away. Example: {-# SPECIALISE f @[] @a #-}. So:
|
|
812 | + |
|
813 | + * The constraint solver has a mode flag `tcsmFullySolveQCIs` that says
|
|
814 | + "fully solve quantified constraint, or leave them alone
|
|
815 | + * When simplifying constraints in a SPECIALISE pragma, we switch on this
|
|
816 | + flag the `SpecPragE` case of `tcSpecPrag`.
|
|
817 | + |
|
818 | + You might worry about the wasted work from failed attempts to fully-solve, but
|
|
819 | + it is seldom repeated (because the constraint solver seldom iterates much).
|
|
820 | + |
|
798 | 821 | Note [Handling old-form SPECIALISE pragmas]
|
799 | 822 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
800 | 823 | NB: this code path is deprecated, and is scheduled to be removed in GHC 9.18, as per #25440.
|
... | ... | @@ -976,12 +999,11 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) |
976 | 999 | tcInferRho spec_e
|
977 | 1000 | |
978 | 1001 | -- (2) Solve the resulting wanteds
|
979 | - -- When doing so, switch on `tcsmFullySolveQCIs`; see (WFA4) in
|
|
980 | - -- Note [Solving a Wanted forall-constraint] in GHC.Tc.Solver.Solve
|
|
981 | 1002 | ; ev_binds_var <- newTcEvBinds
|
982 | 1003 | ; spec_e_wanted <- setTcLevel rhs_tclvl $
|
983 | 1004 | runTcSWithEvBinds ev_binds_var $
|
984 | 1005 | setTcSMode (vanillaTcSMode { tcsmFullySolveQCIs = True }) $
|
1006 | + -- tcsmFullySolveQCIs: see (NFS1)a
|
|
985 | 1007 | solveWanteds spec_e_wanted
|
986 | 1008 | ; spec_e_wanted <- liftZonkM $ zonkWC spec_e_wanted
|
987 | 1009 |
... | ... | @@ -1028,15 +1028,15 @@ findInferredDiff annotated_theta inferred_theta |
1028 | 1028 | ; let given_loc = mkGivenLoc topTcLevel (getSkolemInfo unkSkol) (mkCtLocEnv lcl_env)
|
1029 | 1029 | given_cts = mkGivens given_loc given_ids
|
1030 | 1030 | |
1031 | - ; (residual, _) <- runTcS $
|
|
1032 | - do { _ <- solveSimpleGivens given_cts
|
|
1033 | - ; solveSimpleWanteds (listToBag (map mkNonCanonical wanteds)) }
|
|
1031 | + ; (residual_wc, _) <- runTcS $
|
|
1032 | + do { _ <- solveSimpleGivens given_cts
|
|
1033 | + ; solveSimpleWanteds (listToBag (map mkNonCanonical wanteds)) }
|
|
1034 | 1034 | -- NB: There are no meta tyvars fromn this level annotated_theta
|
1035 | 1035 | -- because we have either promoted them or unified them
|
1036 | 1036 | -- See `Note [Quantification and partial signatures]` Wrinkle 2
|
1037 | 1037 | |
1038 | 1038 | ; return (map (box_pred . ctPred) $
|
1039 | - bagToList residual) }
|
|
1039 | + bagToList (wc_simple residual_wc)) }
|
|
1040 | 1040 | where
|
1041 | 1041 | box_pred :: PredType -> PredType
|
1042 | 1042 | box_pred pred = case classifyPredType pred of
|
... | ... | @@ -1189,7 +1189,7 @@ tryDefaultGroup wanteds (Proposal assignments) |
1189 | 1189 | | CtWanted wtd <- map ctEvidence wanteds
|
1190 | 1190 | ]
|
1191 | 1191 | ; residual <- solveSimpleWanteds (listToBag new_wanteds)
|
1192 | - ; return $ if isEmptyBag residual then Just (tvs, subst) else Nothing }
|
|
1192 | + ; return $ if isEmptyWC residual then Just (tvs, subst) else Nothing }
|
|
1193 | 1193 | |
1194 | 1194 | | otherwise
|
1195 | 1195 | = return Nothing
|
... | ... | @@ -834,7 +834,7 @@ tryShortCutSolver try_short_cut dict_w@(DictCt { di_ev = ev_w }) |
834 | 834 | |
835 | 835 | -> tryShortCutTcS $ -- tryTcS tries to completely solve some contraints
|
836 | 836 | do { residual <- solveSimpleWanteds (unitBag (CDictCan dict_w))
|
837 | - ; return (isEmptyBag residual) }
|
|
837 | + ; return (isEmptyWC residual) }
|
|
838 | 838 | |
839 | 839 | | otherwise
|
840 | 840 | -> return False }
|
... | ... | @@ -196,9 +196,11 @@ import GHC.Types.Unique.Set( elementOfUniqSet ) |
196 | 196 | import GHC.Types.Id
|
197 | 197 | import GHC.Types.Basic (allImportLevels)
|
198 | 198 | import GHC.Types.ThLevelIndex (thLevelIndexFromImportLevel)
|
199 | +import GHC.Types.SrcLoc
|
|
199 | 200 | |
200 | 201 | import GHC.Unit.Module
|
201 | 202 | import qualified GHC.Rename.Env as TcM
|
203 | +import GHC.Rename.Env
|
|
202 | 204 | |
203 | 205 | import GHC.Utils.Outputable
|
204 | 206 | import GHC.Utils.Panic
|
... | ... | @@ -213,12 +215,11 @@ import GHC.Exts (oneShot) |
213 | 215 | import Control.Monad
|
214 | 216 | import Data.Foldable hiding ( foldr1 )
|
215 | 217 | import Data.IORef
|
218 | +import Data.Maybe( catMaybes )
|
|
216 | 219 | import Data.List ( mapAccumL )
|
217 | 220 | import Data.List.NonEmpty ( nonEmpty )
|
218 | 221 | import qualified Data.List.NonEmpty as NE
|
219 | 222 | import qualified Data.Semigroup as S
|
220 | -import GHC.Types.SrcLoc
|
|
221 | -import GHC.Rename.Env
|
|
222 | 223 | import GHC.LanguageExtensions as LangExt
|
223 | 224 | |
224 | 225 | #if defined(DEBUG)
|
... | ... | @@ -920,11 +921,14 @@ vanillaTcSMode = TcSMode { tcsmPmCheck = False |
920 | 921 | instance Outputable TcSMode where
|
921 | 922 | ppr (TcSMode { tcsmPmCheck = pm, tcsmEarlyAbort = ea
|
922 | 923 | , tcsmSkipOverlappable = so, tcsmFullySolveQCIs = fs })
|
923 | - = text "TcSMode" <> (braces $
|
|
924 | - text "pm=" <> ppr pm <> comma <>
|
|
925 | - text "ea=" <> ppr ea <> comma <>
|
|
926 | - text "so=" <> ppr so <> comma <>
|
|
927 | - text "fs=" <> ppr fs)
|
|
924 | + = text "TcSMode" <> (braces $ cat $ punctuate comma $ catMaybes $
|
|
925 | + [ pp_one pm "PmCheck", pp_one ea "EarlyAbort"
|
|
926 | + , pp_one so "SkipOverlappable", pp_one fs "FullySolveQCIs" ])
|
|
927 | + -- We get something like TcSMode{EarlyAbort,FullySolveQCIs},
|
|
928 | + -- mentioning just the flags that are on
|
|
929 | + where
|
|
930 | + pp_one True s = Just (text s)
|
|
931 | + pp_one False _ = Nothing
|
|
928 | 932 | |
929 | 933 | {- Note [TcSMode]
|
930 | 934 | ~~~~~~~~~~~~~~~~~
|
... | ... | @@ -119,22 +119,18 @@ simplify_loop n limit definitely_redo_implications |
119 | 119 | , int (lengthBag simples) <+> text "simples to solve" ])
|
120 | 120 | ; traceTcS "simplify_loop: wc =" (ppr wc)
|
121 | 121 | |
122 | - ; (unifs1, simples1) <- reportUnifications $ -- See Note [Superclass iteration]
|
|
123 | - solveSimpleWanteds simples
|
|
122 | + ; (unifs1, wc1) <- reportUnifications $ -- See Note [Superclass iteration]
|
|
123 | + solveSimpleWanteds simples
|
|
124 | 124 | -- Any insoluble constraints are in 'simples' and so get rewritten
|
125 | 125 | -- See Note [Rewrite insolubles] in GHC.Tc.Solver.InertSet
|
126 | 126 | |
127 | - -- Now try to solve any Wanted QCInsts in `simples1`
|
|
128 | - ; (simples', implics_from_qcis) <- solveWantedQCIs simples1
|
|
129 | - |
|
130 | 127 | -- Next, solve implications from wc_impl
|
131 | 128 | ; implics' <- if not definitely_redo_implications -- See Note [Superclass iteration]
|
132 | 129 | && unifs1 == 0 -- for this conditional
|
133 | 130 | then return implics
|
134 | 131 | else solveNestedImplications implics
|
135 | 132 | |
136 | - ; let wc' = wc { wc_simple = simples'
|
|
137 | - , wc_impl = implics' `unionBags` implics_from_qcis }
|
|
133 | + ; let wc' = wc1 { wc_impl = wc_impl wc1 `unionBags` implics' }
|
|
138 | 134 | |
139 | 135 | ; unif_happened <- resetUnificationFlag
|
140 | 136 | ; csTraceTcS $ text "unif_happened" <+> ppr unif_happened
|
... | ... | @@ -1020,7 +1016,9 @@ solveSimpleGivens givens |
1020 | 1016 | ; when (notNull new_givens) $
|
1021 | 1017 | go new_givens }
|
1022 | 1018 | |
1023 | -solveSimpleWanteds :: Cts -> TcS Cts
|
|
1019 | +solveSimpleWanteds :: Cts -> TcS WantedConstraints
|
|
1020 | +-- Returns unsolved constraints, mostly just flat ones (Cts),
|
|
1021 | +-- but also any unsolved implications arising from forall-constraints
|
|
1024 | 1022 | -- The result is not necessarily zonked
|
1025 | 1023 | solveSimpleWanteds simples
|
1026 | 1024 | = do { mode <- getTcSMode
|
... | ... | @@ -1032,43 +1030,59 @@ solveSimpleWanteds simples |
1032 | 1030 | , text "Inerts:" <+> ppr inerts
|
1033 | 1031 | , text "Wanteds to solve:" <+> ppr simples ]
|
1034 | 1032 | |
1035 | - ; (n,wc) <- go 1 (solverIterations dflags) simples
|
|
1033 | + ; (n,simples',implics') <- go (solverIterations dflags) 1 emptyBag simples
|
|
1034 | + |
|
1035 | + ; let unsolved_wc = emptyWC { wc_simple = simples', wc_impl = implics' }
|
|
1036 | 1036 | |
1037 | 1037 | ; traceTcS "solveSimpleWanteds end }" $
|
1038 | 1038 | vcat [ text "iterations =" <+> ppr n
|
1039 | - , text "residual =" <+> ppr wc ]
|
|
1040 | - ; return wc }
|
|
1039 | + , text "residual =" <+> ppr unsolved_wc ]
|
|
1040 | + |
|
1041 | + ; return unsolved_wc }
|
|
1041 | 1042 | where
|
1042 | - go :: Int -> IntWithInf -> Cts -> TcS (Int, Cts)
|
|
1043 | + go :: IntWithInf -- Limit
|
|
1044 | + -> Int -- Iteration number
|
|
1045 | + -> Bag Implication -- Accumulating parameter: unsolved implications
|
|
1046 | + -> Cts -- Try to solve these
|
|
1047 | + -> TcS (Int, Cts, Bag Implication)
|
|
1043 | 1048 | -- See Note [The solveSimpleWanteds loop]
|
1044 | - go n limit wc
|
|
1049 | + go limit n implics wanted
|
|
1045 | 1050 | | n `intGtLimit` limit
|
1046 | 1051 | = failTcS $ TcRnSimplifierTooManyIterations
|
1047 | - simples limit (emptyWC { wc_simple = wc })
|
|
1048 | - | isEmptyBag wc
|
|
1049 | - = return (n,wc)
|
|
1052 | + simples limit
|
|
1053 | + (emptyWC { wc_simple = wanted, wc_impl = implics })
|
|
1054 | + |
|
1055 | + | isEmptyBag wanted
|
|
1056 | + = return (n, wanted, implics)
|
|
1057 | + |
|
1050 | 1058 | | otherwise
|
1051 | 1059 | = do { -- Solve
|
1052 | - wc1 <- solve_simple_wanteds wc
|
|
1060 | + (wanted1, implics1) <- solve_one wanted
|
|
1061 | + ; let implics2 = implics `unionBags` implics1
|
|
1053 | 1062 | |
1054 | 1063 | -- Run plugins
|
1055 | - -- NB: runTcPluginsWanted has a fast path for empty wc1,
|
|
1056 | - -- which is the common case
|
|
1057 | - ; (rerun_plugin, wc2) <- runTcPluginsWanted wc1
|
|
1064 | + -- NB: runTcPluginsWanted has a fast path for
|
|
1065 | + -- empty wanted1, which is the common case
|
|
1066 | + ; (rerun_plugin, wanted2) <- runTcPluginsWanted wanted1
|
|
1058 | 1067 | |
1059 | 1068 | ; if rerun_plugin
|
1060 | 1069 | then do { traceTcS "solveSimple going round again:" (ppr rerun_plugin)
|
1061 | - ; go (n+1) limit wc2 } -- Loop
|
|
1062 | - else return (n, wc2) } -- Done
|
|
1070 | + ; go limit (n+1) implics2 wanted2 } -- Loop
|
|
1071 | + else return (n, wanted2, implics2) } -- Done
|
|
1063 | 1072 | |
1064 | 1073 | |
1065 | -solve_simple_wanteds :: Cts -> TcS Cts
|
|
1066 | --- Try solving these constraints
|
|
1067 | --- Affects the unification state (of course) but not the inert set
|
|
1068 | --- The result is not necessarily zonked
|
|
1069 | -solve_simple_wanteds simples
|
|
1070 | - = nestTcS $ do { solveSimples simples
|
|
1071 | - ; getUnsolvedInerts }
|
|
1074 | + solve_one :: Cts -> TcS (Cts, Bag Implication)
|
|
1075 | + -- Try solving these constraints
|
|
1076 | + -- Affects the unification state (of course) but not the inert set
|
|
1077 | + -- The result is not necessarily zonked
|
|
1078 | + solve_one simples
|
|
1079 | + = nestTcS $
|
|
1080 | + do { solveSimples simples
|
|
1081 | + ; simples' <- getUnsolvedInerts
|
|
1082 | + -- Now try to solve any Wanted quantified
|
|
1083 | + -- constraints (i.e. QCInsts) in `simples1`
|
|
1084 | + ; solveWantedQCIs simples' }
|
|
1085 | + |
|
1072 | 1086 | |
1073 | 1087 | {- Note [The solveSimpleWanteds loop]
|
1074 | 1088 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
... | ... | @@ -1320,25 +1334,24 @@ where <binds> is filled in by solving the implication constraint. |
1320 | 1334 | What we actually do is this:
|
1321 | 1335 | |
1322 | 1336 | * In `solveForAll` we see if we have an identical quantified constraint
|
1323 | - to solve it (using tryInertQCs), and then just add it to `inert_qcis :: [QCInst]`
|
|
1324 | - See Note [Solving Wanted QCs from Given QCs]
|
|
1337 | + to solve it (using tryInertQCs). In particular, solve a Wanted QCI
|
|
1338 | + from an identical Given. This is more than a simple optimisation:
|
|
1339 | + see Note [Solving Wanted QCs from Given QCs]
|
|
1325 | 1340 | |
1326 | -* In the main solver loop, `GHC.Tc.Solver.Solve.simplify_loop`:
|
|
1341 | + If not, just stash it in `inert_qcis :: [QCInst]`. (If it's a Given
|
|
1342 | + we can use it to solve other constraints; if a Wanted we will solve
|
|
1343 | + it later using `solveWantedQCIs`.)
|
|
1327 | 1344 | |
1328 | - - We attempt to solve the `wc_simple` constraints with `solveSimpleWanteds`
|
|
1329 | - Unsolved quantified constraints just accumulate in the `inert_qcis` field
|
|
1330 | - of the `InertSet`.
|
|
1345 | +* In the main `solveSimpleWanteds` (specifically `solve_one`):
|
|
1331 | 1346 | |
1332 | - - Then we use `solveWantedQCIs` to solve any quantified constraints. It usually
|
|
1333 | - turns the `QCInst` into an `Implication`; but not invariably (WFA4)
|
|
1347 | + - We attempt to solve the `wc_simple` constraints with `solveSimples`
|
|
1348 | + Unsolved quantified constraints just accumulate in the `inert_qcis` field
|
|
1349 | + of the `InertSet`.
|
|
1334 | 1350 | |
1335 | -Wrinkles:
|
|
1351 | + - Then we use `solveWantedQCIs` to solve any quantified constraints. That
|
|
1352 | + often turns the `QCInst` into an `Implication`; but not invariably (WFA4)
|
|
1336 | 1353 | |
1337 | -(WFA1) We can take a more straightforward path when there is a matching Given, e.g.
|
|
1338 | - [W] dg :: forall c d. (Eq c, Ord d) => C x c d
|
|
1339 | - In this case, it's better to directly solve the Wanted from the Given, instead
|
|
1340 | - of building an implication. This is more than a simple optimisation; see
|
|
1341 | - Note [Solving Wanted QCs from Given QCs].
|
|
1354 | +Wrinkles:
|
|
1342 | 1355 | |
1343 | 1356 | (WFA2) Termination: see #19690. We want to maintain the invariant (QC-INV):
|
1344 | 1357 | |
... | ... | @@ -1364,27 +1377,9 @@ Wrinkles: |
1364 | 1377 | So the `IsQC` origin carries that info, and `GHC.Tc.Errors.Ppr.pprQCOriginExtra`
|
1365 | 1378 | prints the extra info.
|
1366 | 1379 | |
1367 | -(WFA4) Consider
|
|
1368 | - f :: forall f a. (Ix a, forall x. Eq x => Eq (f x)) => a -> f a
|
|
1369 | - {-# SPECIALISE f :: forall f. (forall x. Eq x => Eq (f x)) => Int -> f Int #-}
|
|
1370 | - This SPECIALISE is treated like an expression with a type signature, so
|
|
1371 | - we instantiate the constraints, simplify them and re-generalise. From the
|
|
1372 | - instantiation we get [W] d :: (forall x. Eq a => Eq (f x))
|
|
1373 | - and we want to generalise over that. We do not want to attempt to solve it
|
|
1374 | - and then get stuck, and emit an error message. If we can't solve it, it is
|
|
1375 | - much, much better to leave it alone.
|
|
1376 | - |
|
1377 | - We still need to simplify quantified constraints that can be /fully solved/
|
|
1378 | - from instances, otherwise we would never be able to specialise them
|
|
1379 | - away. Example: {-# SPECIALISE f @[] @a #-}. So:
|
|
1380 | - |
|
1381 | - * The constraint solver has a mode flag `tcsmFullySolveQCIs` that says
|
|
1382 | - "fully solve quantified constraint, or leave them alone
|
|
1383 | - * When simplifying constraints in a SPECIALISE pragma, we switch on this
|
|
1384 | - flag (see `GHC.Tc.Gen.Sig.tcSpecPrag`, the `SpecSigE` case).
|
|
1385 | - |
|
1386 | - You might worry about the wasted work from failed attempts to fully-solve, but
|
|
1387 | - it is seldom repeated (because the constraint solver seldom iterates much).
|
|
1380 | +(WFA4) When `tcsmFullySolveQCIs` is on, we adopt an all-or-nothing strategy:
|
|
1381 | + either solve the forall-constraint /fully/ or do nothing at all.
|
|
1382 | + Why? See (NFS1) in Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig
|
|
1388 | 1383 | |
1389 | 1384 | (WFA5) Why not /always/ us the all-or-nothing strategy, so we don't need a
|
1390 | 1385 | flag? Several reasons:
|
... | ... | @@ -1579,7 +1574,7 @@ solveWantedQCI mode ct@(CQuantCan (QCI { qci_ev = ev, qci_tvs = tvs |
1579 | 1574 | return (Left ct)
|
1580 | 1575 | |
1581 | 1576 | | otherwise
|
1582 | - -> -- Commit to the (partuly or fully solved) implication
|
|
1577 | + -> -- Commit to the (partly or fully solved) implication
|
|
1583 | 1578 | -- See (WFA5) in Note [Solving a Wanted forall-constraint]
|
1584 | 1579 | -- Record evidence and return residual implication
|
1585 | 1580 | -- NB: even if it is fully solved we must return it, because it is
|
... | ... | @@ -2,7 +2,7 @@ module GHC.Tc.Solver.Solve where |
2 | 2 | |
3 | 3 | import Prelude( Bool )
|
4 | 4 | import GHC.Tc.Solver.Monad( TcS )
|
5 | -import GHC.Tc.Types.Constraint( Cts, Implication )
|
|
5 | +import GHC.Tc.Types.Constraint( Cts, Implication, WantedConstraints )
|
|
6 | 6 | |
7 | -solveSimpleWanteds :: Cts -> TcS Cts
|
|
7 | +solveSimpleWanteds :: Cts -> TcS WantedConstraints
|
|
8 | 8 | trySolveImplication :: Implication -> TcS Bool |
... | ... | @@ -956,7 +956,14 @@ nestedEvIdsOfTerm tm = fvVarSet (filterFV isNestedEvId (evTermFVs tm)) |
956 | 956 | evTermFVs :: EvTerm -> FV
|
957 | 957 | evTermFVs (EvExpr e) = exprFVs e
|
958 | 958 | evTermFVs (EvTypeable _ ev) = evFVsOfTypeable ev
|
959 | -evTermFVs (EvFun {}) = emptyFV -- See Note [Free vars of EvFun]
|
|
959 | +evTermFVs (EvFun { et_tvs = tvs, et_given = given
|
|
960 | + , et_binds = tc_ev_binds, et_body = v })
|
|
961 | + = case tc_ev_binds of
|
|
962 | + TcEvBinds {} -> emptyFV -- See Note [Free vars of EvFun]
|
|
963 | + EvBinds binds -> addBndrsFV bndrs fvs
|
|
964 | + where
|
|
965 | + fvs = foldr (unionFV . evTermFVs . eb_rhs) (unitFV v) binds
|
|
966 | + bndrs = foldr ((:) . eb_lhs) (tvs ++ given) binds
|
|
960 | 967 | |
961 | 968 | evTermFVss :: [EvTerm] -> FV
|
962 | 969 | evTermFVss = mapUnionFV evTermFVs
|
... | ... | @@ -975,12 +982,15 @@ Finding the free vars of an EvFun is made tricky by the fact the |
975 | 982 | bindings et_binds may be a mutable variable. Fortunately, we
|
976 | 983 | can just squeeze by. Here's how.
|
977 | 984 | |
978 | -* evTermFVs is used only by GHC.Tc.Solver.neededEvVars.
|
|
979 | -* Each EvBindsVar in an et_binds field of an EvFun is /also/ in the
|
|
980 | - ic_binds field of an Implication
|
|
981 | -* So we can track usage via the processing for that implication,
|
|
982 | - (see Note [Tracking redundant constraints] in GHC.Tc.Solver).
|
|
983 | - We can ignore usage from the EvFun altogether.
|
|
985 | +* /During/ typechecking, `evTermFVs` is used only by `GHC.Tc.Solver.neededEvVars`
|
|
986 | + * Each EvBindsVar in an et_binds field of an EvFun is /also/ in the
|
|
987 | + ic_binds field of an Implication
|
|
988 | + * So we can track usage via the processing for that implication,
|
|
989 | + (see Note [Tracking redundant constraints] in GHC.Tc.Solver).
|
|
990 | + We can ignore usage from the EvFun altogether.
|
|
991 | + |
|
992 | +* /After/ typechecking `evTermFVs` is used by `GHC.Iface.Ext.Ast`, but by
|
|
993 | + then it has been zonked so we can get at the bindings.
|
|
984 | 994 | -}
|
985 | 995 | |
986 | 996 | {- *********************************************************************
|