Simon Peyton Jones pushed to branch wip/T26115 at Glasgow Haskell Compiler / GHC
Commits:
-
592bf1aa
by Simon Peyton Jones at 2025-06-25T15:37:39+01:00
12 changed files:
- compiler/GHC/HsToCore/Binds.hs
- 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/InertSet.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
- compiler/GHC/Tc/Zonk/Type.hs
- testsuite/tests/typecheck/should_compile/T23171.hs
Changes:
... | ... | @@ -1896,10 +1896,10 @@ dsEvTerm (EvExpr e) = return e |
1896 | 1896 | dsEvTerm (EvTypeable ty ev) = dsEvTypeable ty ev
|
1897 | 1897 | dsEvTerm (EvFun { et_tvs = tvs, et_given = given
|
1898 | 1898 | , et_binds = ev_binds, et_body = wanted_id })
|
1899 | - = do { dsTcEvBinds ev_binds $ \ds_ev_binds -> do
|
|
1900 | - { return $ (mkLams (tvs ++ given) $
|
|
1899 | + = do { dsEvBinds ev_binds $ \ds_ev_binds ->
|
|
1900 | + return $ (mkLams (tvs ++ given) $
|
|
1901 | 1901 | mkCoreLets ds_ev_binds $
|
1902 | - Var wanted_id) } }
|
|
1902 | + Var wanted_id) }
|
|
1903 | 1903 | |
1904 | 1904 | |
1905 | 1905 | {-**********************************************************************
|
... | ... | @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType |
39 | 39 | import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX
|
40 | 40 | , emitResidualConstraints )
|
41 | 41 | import GHC.Tc.Solver.Solve( solveWanteds )
|
42 | -import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag )
|
|
42 | +import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds )
|
|
43 | 43 | import GHC.Tc.Validity ( checkValidType )
|
44 | 44 | |
45 | 45 | import GHC.Tc.Utils.Monad
|
... | ... | @@ -1042,7 +1042,7 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) |
1042 | 1042 | -- (2) Solve the resulting wanteds in TcSSpecPrag mode.
|
1043 | 1043 | ; ev_binds_var <- newTcEvBinds
|
1044 | 1044 | ; spec_e_wanted <- setTcLevel rhs_tclvl $
|
1045 | - runTcSSpecPrag ev_binds_var $
|
|
1045 | + runTcSWithEvBinds ev_binds_var $
|
|
1046 | 1046 | solveWanteds spec_e_wanted
|
1047 | 1047 | ; spec_e_wanted <- liftZonkM $ zonkWC spec_e_wanted
|
1048 | 1048 |
... | ... | @@ -1036,8 +1036,7 @@ findInferredDiff annotated_theta inferred_theta |
1036 | 1036 | -- See `Note [Quantification and partial signatures]` Wrinkle 2
|
1037 | 1037 | |
1038 | 1038 | ; return (map (box_pred . ctPred) $
|
1039 | - bagToList $
|
|
1040 | - wc_simple residual) }
|
|
1039 | + bagToList residual) }
|
|
1041 | 1040 | where
|
1042 | 1041 | box_pred :: PredType -> PredType
|
1043 | 1042 | box_pred pred = case classifyPredType pred of
|
... | ... | @@ -1188,8 +1188,8 @@ tryDefaultGroup wanteds (Proposal assignments) |
1188 | 1188 | ; new_wanteds <- sequence [ new_wtd_ct wtd
|
1189 | 1189 | | CtWanted wtd <- map ctEvidence wanteds
|
1190 | 1190 | ]
|
1191 | - ; residual_wc <- solveSimpleWanteds (listToBag new_wanteds)
|
|
1192 | - ; return $ if isEmptyWC residual_wc then Just (tvs, subst) else Nothing }
|
|
1191 | + ; residual <- solveSimpleWanteds (listToBag new_wanteds)
|
|
1192 | + ; return $ if isEmptyBag residual then Just (tvs, subst) else Nothing }
|
|
1193 | 1193 | |
1194 | 1194 | | otherwise
|
1195 | 1195 | = return Nothing
|
... | ... | @@ -702,10 +702,10 @@ tryInertDicts :: DictCt -> SolverStage () |
702 | 702 | tryInertDicts dict_ct
|
703 | 703 | = Stage $ do { inerts <- getInertCans
|
704 | 704 | ; mode <- getTcSMode
|
705 | - -- In TcSSpecPrag mode we do not look at Givens; that's the point
|
|
705 | + -- In TcSShortCut mode we do not look at Givens; that's the point
|
|
706 | 706 | -- Looking at Wanteds would be OK but no real benefit
|
707 | 707 | ; case mode of
|
708 | - TcSSpecPrag -> continueWith ()
|
|
708 | + TcSShortCut -> continueWith ()
|
|
709 | 709 | _other -> try_inert_dicts inerts dict_ct }
|
710 | 710 | |
711 | 711 | try_inert_dicts :: InertCans -> DictCt -> TcS (StopOrContinue ())
|
... | ... | @@ -774,9 +774,9 @@ tryShortCutSolver try_short_cut dict_w@(DictCt { di_ev = ev_w }) |
774 | 774 | -> tryTcS $ -- tryTcS tries to completely solve some contraints
|
775 | 775 | -- Inherit the current solved_dicts, so that one invocation of
|
776 | 776 | -- tryShortCutSolver can benefit from the work of earlier invocations
|
777 | - setTcSMode TcSSpecPrag $
|
|
778 | - do { wc <- solveSimpleWanteds (unitBag (CDictCan dict_w))
|
|
779 | - ; return (isSolvedWC wc) }
|
|
777 | + setTcSMode TcSShortCut $
|
|
778 | + do { residual <- solveSimpleWanteds (unitBag (CDictCan dict_w))
|
|
779 | + ; return (isEmptyBag residual) }
|
|
780 | 780 | |
781 | 781 | | otherwise
|
782 | 782 | -> return False }
|
... | ... | @@ -11,7 +11,6 @@ module GHC.Tc.Solver.InertSet ( |
11 | 11 | extendWorkListEq, extendWorkListChildEqs,
|
12 | 12 | extendWorkListRewrittenEqs,
|
13 | 13 | appendWorkList,
|
14 | - extendWorkListImplic, extendWorkListImplics,
|
|
15 | 14 | workListSize,
|
16 | 15 | |
17 | 16 | -- * The inert set
|
... | ... | @@ -155,17 +154,6 @@ So we arrange to put these particular class constraints in the wl_eqs. |
155 | 154 | NB: since we do not currently apply the substitution to the
|
156 | 155 | inert_solved_dicts, the knot-tying still seems a bit fragile.
|
157 | 156 | But this makes it better.
|
158 | - |
|
159 | -Note [Residual implications]
|
|
160 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
161 | -The wl_implics in the WorkList are the residual implication
|
|
162 | -constraints that are generated while solving or canonicalising the
|
|
163 | -current worklist. Specifically, when canonicalising
|
|
164 | - (forall a. t1 ~ forall a. t2)
|
|
165 | -from which we get the implication
|
|
166 | - (forall a. t1 ~ t2)
|
|
167 | -See GHC.Tc.Solver.Monad.deferTcSForAllEq
|
|
168 | - |
|
169 | 157 | -}
|
170 | 158 | |
171 | 159 | -- See Note [WorkList priorities]
|
... | ... | @@ -187,8 +175,6 @@ data WorkList |
187 | 175 | -- in GHC.Tc.Types.Constraint for more details.
|
188 | 176 | |
189 | 177 | , wl_rest :: [Ct]
|
190 | - |
|
191 | - , wl_implics :: Bag Implication -- See Note [Residual implications]
|
|
192 | 178 | }
|
193 | 179 | |
194 | 180 | isNominalEqualityCt :: Ct -> Bool
|
... | ... | @@ -203,15 +189,12 @@ isNominalEqualityCt ct |
203 | 189 | |
204 | 190 | appendWorkList :: WorkList -> WorkList -> WorkList
|
205 | 191 | appendWorkList
|
206 | - (WL { wl_eqs_N = eqs1_N, wl_eqs_X = eqs1_X, wl_rw_eqs = rw_eqs1
|
|
207 | - , wl_rest = rest1, wl_implics = implics1 })
|
|
208 | - (WL { wl_eqs_N = eqs2_N, wl_eqs_X = eqs2_X, wl_rw_eqs = rw_eqs2
|
|
209 | - , wl_rest = rest2, wl_implics = implics2 })
|
|
192 | + (WL { wl_eqs_N = eqs1_N, wl_eqs_X = eqs1_X, wl_rw_eqs = rw_eqs1, wl_rest = rest1 })
|
|
193 | + (WL { wl_eqs_N = eqs2_N, wl_eqs_X = eqs2_X, wl_rw_eqs = rw_eqs2, wl_rest = rest2 })
|
|
210 | 194 | = WL { wl_eqs_N = eqs1_N ++ eqs2_N
|
211 | 195 | , wl_eqs_X = eqs1_X ++ eqs2_X
|
212 | 196 | , wl_rw_eqs = rw_eqs1 ++ rw_eqs2
|
213 | - , wl_rest = rest1 ++ rest2
|
|
214 | - , wl_implics = implics1 `unionBags` implics2 }
|
|
197 | + , wl_rest = rest1 ++ rest2 }
|
|
215 | 198 | |
216 | 199 | workListSize :: WorkList -> Int
|
217 | 200 | workListSize (WL { wl_eqs_N = eqs_N, wl_eqs_X = eqs_X, wl_rw_eqs = rw_eqs, wl_rest = rest })
|
... | ... | @@ -269,12 +252,6 @@ extendWorkListNonEq :: Ct -> WorkList -> WorkList |
269 | 252 | -- Extension by non equality
|
270 | 253 | extendWorkListNonEq ct wl = wl { wl_rest = ct : wl_rest wl }
|
271 | 254 | |
272 | -extendWorkListImplic :: Implication -> WorkList -> WorkList
|
|
273 | -extendWorkListImplic implic wl = wl { wl_implics = implic `consBag` wl_implics wl }
|
|
274 | - |
|
275 | -extendWorkListImplics :: Bag Implication -> WorkList -> WorkList
|
|
276 | -extendWorkListImplics implics wl = wl { wl_implics = implics `unionBags` wl_implics wl }
|
|
277 | - |
|
278 | 255 | extendWorkListCt :: Ct -> WorkList -> WorkList
|
279 | 256 | -- Agnostic about what kind of constraint
|
280 | 257 | extendWorkListCt ct wl
|
... | ... | @@ -298,18 +275,18 @@ extendWorkListCts :: Cts -> WorkList -> WorkList |
298 | 275 | extendWorkListCts cts wl = foldr extendWorkListCt wl cts
|
299 | 276 | |
300 | 277 | isEmptyWorkList :: WorkList -> Bool
|
301 | -isEmptyWorkList (WL { wl_eqs_N = eqs_N, wl_eqs_X = eqs_X, wl_rw_eqs = rw_eqs
|
|
302 | - , wl_rest = rest, wl_implics = implics })
|
|
303 | - = null eqs_N && null eqs_X && null rw_eqs && null rest && isEmptyBag implics
|
|
278 | +isEmptyWorkList (WL { wl_eqs_N = eqs_N, wl_eqs_X = eqs_X
|
|
279 | + , wl_rw_eqs = rw_eqs, wl_rest = rest })
|
|
280 | + = null eqs_N && null eqs_X && null rw_eqs && null rest
|
|
304 | 281 | |
305 | 282 | emptyWorkList :: WorkList
|
306 | 283 | emptyWorkList = WL { wl_eqs_N = [], wl_eqs_X = []
|
307 | - , wl_rw_eqs = [], wl_rest = [], wl_implics = emptyBag }
|
|
284 | + , wl_rw_eqs = [], wl_rest = [] }
|
|
308 | 285 | |
309 | 286 | -- Pretty printing
|
310 | 287 | instance Outputable WorkList where
|
311 | - ppr (WL { wl_eqs_N = eqs_N, wl_eqs_X = eqs_X, wl_rw_eqs = rw_eqs
|
|
312 | - , wl_rest = rest, wl_implics = implics })
|
|
288 | + ppr (WL { wl_eqs_N = eqs_N, wl_eqs_X = eqs_X
|
|
289 | + , wl_rw_eqs = rw_eqs, wl_rest = rest })
|
|
313 | 290 | = text "WL" <+> (braces $
|
314 | 291 | vcat [ ppUnless (null eqs_N) $
|
315 | 292 | text "Eqs_N =" <+> vcat (map ppr eqs_N)
|
... | ... | @@ -319,9 +296,6 @@ instance Outputable WorkList where |
319 | 296 | text "RwEqs =" <+> vcat (map ppr rw_eqs)
|
320 | 297 | , ppUnless (null rest) $
|
321 | 298 | text "Non-eqs =" <+> vcat (map ppr rest)
|
322 | - , ppUnless (isEmptyBag implics) $
|
|
323 | - ifPprDebug (text "Implics =" <+> vcat (map ppr (bagToList implics)))
|
|
324 | - (text "(Implics omitted)")
|
|
325 | 299 | ])
|
326 | 300 | |
327 | 301 | {- *********************************************************************
|
... | ... | @@ -17,12 +17,10 @@ module GHC.Tc.Solver.Monad ( |
17 | 17 | -- The TcS monad
|
18 | 18 | TcS(..), TcSEnv(..),
|
19 | 19 | runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts,
|
20 | - runTcSSpecPrag,
|
|
21 | 20 | failTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS,
|
22 | 21 | runTcSEqualities,
|
23 | 22 | nestTcS, nestImplicTcS, tryTcS,
|
24 | 23 | setEvBindsTcS, setTcLevelTcS,
|
25 | - emitImplicationTcS, emitTvImplicationTcS,
|
|
26 | 24 | emitFunDepWanteds,
|
27 | 25 | |
28 | 26 | selectNextWorkItem,
|
... | ... | @@ -746,8 +744,7 @@ get_sc_pending this_lvl ic@(IC { inert_dicts = dicts, inert_insts = insts }) |
746 | 744 | -- We only want Givens from this level; see (3a) in
|
747 | 745 | -- Note [The superclass story] in GHC.Tc.Solver.Dict
|
748 | 746 | |
749 | -getUnsolvedInerts :: TcS ( Bag Implication
|
|
750 | - , Cts ) -- All simple constraints
|
|
747 | +getUnsolvedInerts :: TcS Cts -- All simple constraints
|
|
751 | 748 | -- Return all the unsolved [Wanted] constraints
|
752 | 749 | --
|
753 | 750 | -- Post-condition: the returned simple constraints are all fully zonked
|
... | ... | @@ -767,20 +764,17 @@ getUnsolvedInerts |
767 | 764 | unsolved_dicts = foldDicts (add_if_unsolved CDictCan) idicts emptyCts
|
768 | 765 | unsolved_qcis = foldr (add_if_unsolved CQuantCan) emptyCts qcis
|
769 | 766 | |
770 | - ; implics <- getWorkListImplics
|
|
771 | - |
|
772 | 767 | ; traceTcS "getUnsolvedInerts" $
|
773 | 768 | vcat [ text " tv eqs =" <+> ppr unsolved_tv_eqs
|
774 | 769 | , text "fun eqs =" <+> ppr unsolved_fun_eqs
|
775 | 770 | , text "dicts =" <+> ppr unsolved_dicts
|
776 | - , text "irreds =" <+> ppr unsolved_irreds
|
|
777 | - , text "implics =" <+> ppr implics ]
|
|
778 | - |
|
779 | - ; return ( implics, unsolved_tv_eqs `unionBags`
|
|
780 | - unsolved_fun_eqs `unionBags`
|
|
781 | - unsolved_irreds `unionBags`
|
|
782 | - unsolved_dicts `unionBags`
|
|
783 | - unsolved_qcis ) }
|
|
771 | + , text "irreds =" <+> ppr unsolved_irreds ]
|
|
772 | + |
|
773 | + ; return ( unsolved_tv_eqs `unionBags`
|
|
774 | + unsolved_fun_eqs `unionBags`
|
|
775 | + unsolved_irreds `unionBags`
|
|
776 | + unsolved_dicts `unionBags`
|
|
777 | + unsolved_qcis ) }
|
|
784 | 778 | where
|
785 | 779 | add_if_unsolved :: (a -> Ct) -> a -> Cts -> Cts
|
786 | 780 | add_if_unsolved mk_ct thing cts
|
... | ... | @@ -938,7 +932,7 @@ data TcSMode |
938 | 932 | = TcSVanilla -- ^ Normal constraint solving
|
939 | 933 | | TcSPMCheck -- ^ Used when doing patterm match overlap checks
|
940 | 934 | | TcSEarlyAbort -- ^ Abort early on insoluble constraints
|
941 | - | TcSSpecPrag -- ^ Fully solve all constraints
|
|
935 | + | TcSShortCut -- ^ Fully solve all constraints, without using local Givens
|
|
942 | 936 | deriving (Eq)
|
943 | 937 | |
944 | 938 | {- Note [TcSMode]
|
... | ... | @@ -1135,10 +1129,6 @@ runTcSEarlyAbort tcs |
1135 | 1129 | -- | Run the 'TcS' monad in 'TcSSpecPrag' mode, which either fully solves
|
1136 | 1130 | -- individual Wanted quantified constraints or leaves them alone.
|
1137 | 1131 | --
|
1138 | --- See Note [TcSSpecPrag].
|
|
1139 | -runTcSSpecPrag :: EvBindsVar -> TcS a -> TcM a
|
|
1140 | -runTcSSpecPrag ev_binds_var tcs
|
|
1141 | - = runTcSWithEvBinds' TcSSpecPrag ev_binds_var tcs
|
|
1142 | 1132 | |
1143 | 1133 | {- Note [TcSSpecPrag]
|
1144 | 1134 | ~~~~~~~~~~~~~~~~~~~~~
|
... | ... | @@ -1390,46 +1380,6 @@ updateInertsWith current_inerts |
1390 | 1380 | = current_inerts { inert_solved_dicts = new_solved
|
1391 | 1381 | , inert_safehask = new_safehask }
|
1392 | 1382 | |
1393 | -emitImplicationTcS :: TcLevel -> SkolemInfoAnon
|
|
1394 | - -> [TcTyVar] -- Skolems
|
|
1395 | - -> [EvVar] -- Givens
|
|
1396 | - -> Cts -- Wanteds
|
|
1397 | - -> TcS TcEvBinds
|
|
1398 | --- Add an implication to the TcS monad work-list
|
|
1399 | -emitImplicationTcS new_tclvl skol_info skol_tvs givens wanteds
|
|
1400 | - = do { let wc = emptyWC { wc_simple = wanteds }
|
|
1401 | - ; imp <- wrapTcS $
|
|
1402 | - do { ev_binds_var <- TcM.newTcEvBinds
|
|
1403 | - ; imp <- TcM.newImplication
|
|
1404 | - ; return (imp { ic_tclvl = new_tclvl
|
|
1405 | - , ic_skols = skol_tvs
|
|
1406 | - , ic_given = givens
|
|
1407 | - , ic_wanted = wc
|
|
1408 | - , ic_binds = ev_binds_var
|
|
1409 | - , ic_info = skol_info }) }
|
|
1410 | - |
|
1411 | - ; updWorkListTcS (extendWorkListImplic imp)
|
|
1412 | - ; return (TcEvBinds (ic_binds imp)) }
|
|
1413 | - |
|
1414 | -emitTvImplicationTcS :: TcLevel -> SkolemInfoAnon
|
|
1415 | - -> [TcTyVar] -- Skolems
|
|
1416 | - -> Cts -- Wanteds
|
|
1417 | - -> TcS ()
|
|
1418 | --- Just like emitImplicationTcS but no givens and no bindings
|
|
1419 | -emitTvImplicationTcS new_tclvl skol_info skol_tvs wanteds
|
|
1420 | - = do { let wc = emptyWC { wc_simple = wanteds }
|
|
1421 | - ; imp <- wrapTcS $
|
|
1422 | - do { ev_binds_var <- TcM.newNoTcEvBinds
|
|
1423 | - ; imp <- TcM.newImplication
|
|
1424 | - ; return (imp { ic_tclvl = new_tclvl
|
|
1425 | - , ic_skols = skol_tvs
|
|
1426 | - , ic_wanted = wc
|
|
1427 | - , ic_binds = ev_binds_var
|
|
1428 | - , ic_info = skol_info }) }
|
|
1429 | - |
|
1430 | - ; updWorkListTcS (extendWorkListImplic imp) }
|
|
1431 | - |
|
1432 | - |
|
1433 | 1383 | {- Note [Propagate the solved dictionaries]
|
1434 | 1384 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1435 | 1385 | It's really quite important that nestTcS does not discard the solved
|
... | ... | @@ -1795,12 +1745,6 @@ getWorkList :: TcS WorkList |
1795 | 1745 | getWorkList = do { wl_var <- getTcSWorkListRef
|
1796 | 1746 | ; readTcRef wl_var }
|
1797 | 1747 | |
1798 | -getWorkListImplics :: TcS (Bag Implication)
|
|
1799 | -getWorkListImplics
|
|
1800 | - = do { wl_var <- getTcSWorkListRef
|
|
1801 | - ; wl_curr <- readTcRef wl_var
|
|
1802 | - ; return (wl_implics wl_curr) }
|
|
1803 | - |
|
1804 | 1748 | updWorkListTcS :: (WorkList -> WorkList) -> TcS ()
|
1805 | 1749 | updWorkListTcS f
|
1806 | 1750 | = do { wl_var <- getTcSWorkListRef
|
... | ... | @@ -2017,7 +1961,7 @@ instFlexiXTcM subst (tv:tvs) |
2017 | 1961 | matchGlobalInst :: DynFlags -> Class -> [Type] -> CtLoc -> TcS TcM.ClsInstResult
|
2018 | 1962 | matchGlobalInst dflags cls tys loc
|
2019 | 1963 | = do { mode <- getTcSMode
|
2020 | - ; let short_cut = mode == TcSSpecPrag
|
|
1964 | + ; let short_cut = mode == TcSShortCut
|
|
2021 | 1965 | ; wrapTcS $ TcM.matchGlobalInst dflags short_cut cls tys (Just loc) }
|
2022 | 1966 | |
2023 | 1967 | tcInstSkolTyVarsX :: SkolemInfo -> Subst -> [TyVar] -> TcS (Subst, [TcTyVar])
|
... | ... | @@ -94,6 +94,7 @@ solveWanteds wc@(WC { wc_errors = errs }) |
94 | 94 | ; bb <- TcS.getTcEvBindsMap ev_binds_var
|
95 | 95 | ; traceTcS "solveWanteds }" $
|
96 | 96 | vcat [ text "final wc =" <+> ppr final_wc
|
97 | + , text "ev_binds_var =" <+> ppr ev_binds_var
|
|
97 | 98 | , text "current evbinds =" <+> ppr (evBindMapBinds bb) ]
|
98 | 99 | |
99 | 100 | ; return final_wc }
|
... | ... | @@ -118,19 +119,17 @@ simplify_loop n limit definitely_redo_implications |
118 | 119 | , int (lengthBag simples) <+> text "simples to solve" ])
|
119 | 120 | ; traceTcS "simplify_loop: wc =" (ppr wc)
|
120 | 121 | |
121 | - ; (unifs1, wc1) <- reportUnifications $ -- See Note [Superclass iteration]
|
|
122 | - solveSimpleWanteds simples
|
|
122 | + ; (unifs1, simples1) <- reportUnifications $ -- See Note [Superclass iteration]
|
|
123 | + solveSimpleWanteds simples
|
|
123 | 124 | -- Any insoluble constraints are in 'simples' and so get rewritten
|
124 | 125 | -- See Note [Rewrite insolubles] in GHC.Tc.Solver.InertSet
|
125 | 126 | |
126 | 127 | ; wc2 <- if not definitely_redo_implications -- See Note [Superclass iteration]
|
127 | 128 | && unifs1 == 0 -- for this conditional
|
128 | - && isEmptyBag (wc_impl wc1)
|
|
129 | - then return (wc { wc_simple = wc_simple wc1 }) -- Short cut
|
|
130 | - else do { implics2 <- solveNestedImplications $
|
|
131 | - implics `unionBags` (wc_impl wc1)
|
|
132 | - ; return (wc { wc_simple = wc_simple wc1
|
|
133 | - , wc_impl = implics2 }) }
|
|
129 | + then return (wc { wc_simple = simples1 }) -- Short cut
|
|
130 | + else do { implics1 <- solveNestedImplications implics
|
|
131 | + ; return (wc { wc_simple = simples1
|
|
132 | + , wc_impl = implics1 }) }
|
|
134 | 133 | |
135 | 134 | ; unif_happened <- resetUnificationFlag
|
136 | 135 | ; csTraceTcS $ text "unif_happened" <+> ppr unif_happened
|
... | ... | @@ -978,30 +977,32 @@ solveSimpleGivens givens |
978 | 977 | -- for use by subsequent calls of nestImplicTcS
|
979 | 978 | ; updInertSet (\is -> is { inert_givens = inert_cans is })
|
980 | 979 | |
981 | - ; traceTcS "End solveSimpleGivens }" empty }
|
|
980 | + ; cans <- getInertCans
|
|
981 | + ; traceTcS "End solveSimpleGivens }" (ppr cans) }
|
|
982 | 982 | where
|
983 | 983 | go givens = do { solveSimples (listToBag givens)
|
984 | 984 | ; new_givens <- runTcPluginsGiven
|
985 | 985 | ; when (notNull new_givens) $
|
986 | 986 | go new_givens }
|
987 | 987 | |
988 | -solveSimpleWanteds :: Cts -> TcS WantedConstraints
|
|
988 | +solveSimpleWanteds :: Cts -> TcS Cts
|
|
989 | 989 | -- The result is not necessarily zonked
|
990 | 990 | solveSimpleWanteds simples
|
991 | 991 | = do { traceTcS "solveSimpleWanteds {" (ppr simples)
|
992 | 992 | ; dflags <- getDynFlags
|
993 | - ; (n,wc) <- go 1 (solverIterations dflags) (emptyWC { wc_simple = simples })
|
|
993 | + ; (n,wc) <- go 1 (solverIterations dflags) simples
|
|
994 | 994 | ; traceTcS "solveSimpleWanteds end }" $
|
995 | 995 | vcat [ text "iterations =" <+> ppr n
|
996 | 996 | , text "residual =" <+> ppr wc ]
|
997 | 997 | ; return wc }
|
998 | 998 | where
|
999 | - go :: Int -> IntWithInf -> WantedConstraints -> TcS (Int, WantedConstraints)
|
|
999 | + go :: Int -> IntWithInf -> Cts -> TcS (Int, Cts)
|
|
1000 | 1000 | -- See Note [The solveSimpleWanteds loop]
|
1001 | 1001 | go n limit wc
|
1002 | 1002 | | n `intGtLimit` limit
|
1003 | - = failTcS $ TcRnSimplifierTooManyIterations simples limit wc
|
|
1004 | - | isEmptyBag (wc_simple wc)
|
|
1003 | + = failTcS $ TcRnSimplifierTooManyIterations
|
|
1004 | + simples limit (emptyWC { wc_simple = wc })
|
|
1005 | + | isEmptyBag wc
|
|
1005 | 1006 | = return (n,wc)
|
1006 | 1007 | | otherwise
|
1007 | 1008 | = do { -- Solve
|
... | ... | @@ -1018,17 +1019,13 @@ solveSimpleWanteds simples |
1018 | 1019 | else return (n, wc2) } -- Done
|
1019 | 1020 | |
1020 | 1021 | |
1021 | -solve_simple_wanteds :: WantedConstraints -> TcS WantedConstraints
|
|
1022 | +solve_simple_wanteds :: Cts -> TcS Cts
|
|
1022 | 1023 | -- Try solving these constraints
|
1023 | 1024 | -- Affects the unification state (of course) but not the inert set
|
1024 | 1025 | -- The result is not necessarily zonked
|
1025 | -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_errors = errs })
|
|
1026 | - = nestTcS $
|
|
1027 | - do { solveSimples simples1
|
|
1028 | - ; (implics2, unsolved) <- getUnsolvedInerts
|
|
1029 | - ; return (WC { wc_simple = unsolved
|
|
1030 | - , wc_impl = implics1 `unionBags` implics2
|
|
1031 | - , wc_errors = errs }) }
|
|
1026 | +solve_simple_wanteds simples
|
|
1027 | + = nestTcS $ do { solveSimples simples
|
|
1028 | + ; getUnsolvedInerts }
|
|
1032 | 1029 | |
1033 | 1030 | {- Note [The solveSimpleWanteds loop]
|
1034 | 1031 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
... | ... | @@ -1379,13 +1376,14 @@ solveWantedForAll qci tvs theta body_pred |
1379 | 1376 | , ic_skols = skol_tvs
|
1380 | 1377 | , ic_given = given_ev_vars
|
1381 | 1378 | , ic_wanted = emptyWC { wc_simple = wanteds } }
|
1382 | - ; traceTcS "sllveForAll }" (ppr solved)
|
|
1379 | + ; traceTcS "solveForAll }" (ppr solved)
|
|
1380 | + ; evbs <- TcS.getTcEvBindsMap ev_binds_var
|
|
1383 | 1381 | ; if not solved
|
1384 | 1382 | then do { addInertForAll qci
|
1385 | 1383 | ; stopWith (CtWanted wtd) "Wanted forall-constraint:unsolved" }
|
1386 | 1384 | else do { setWantedEvTerm dest EvCanonical $
|
1387 | 1385 | EvFun { et_tvs = skol_tvs, et_given = given_ev_vars
|
1388 | - , et_binds = TcEvBinds ev_binds_var, et_body = w_id }
|
|
1386 | + , et_binds = evBindMapBinds evbs, et_body = w_id }
|
|
1389 | 1387 | ; stopWith (CtWanted wtd) "Wanted forall-constraint:solved" } }
|
1390 | 1388 | where
|
1391 | 1389 | loc_env = ctLocEnv ct_loc
|
... | ... | @@ -1596,13 +1594,13 @@ runTcPluginsGiven |
1596 | 1594 | -- work) and a bag of insolubles. The boolean indicates whether
|
1597 | 1595 | -- 'solveSimpleWanteds' should feed the updated wanteds back into the
|
1598 | 1596 | -- main solver.
|
1599 | -runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints)
|
|
1600 | -runTcPluginsWanted wc@(WC { wc_simple = simples1 })
|
|
1597 | +runTcPluginsWanted :: Cts -> TcS (Bool, Cts)
|
|
1598 | +runTcPluginsWanted simples1
|
|
1601 | 1599 | | isEmptyBag simples1
|
1602 | - = return (False, wc)
|
|
1600 | + = return (False, simples1)
|
|
1603 | 1601 | | otherwise
|
1604 | 1602 | = do { solvers <- getTcPluginSolvers
|
1605 | - ; if null solvers then return (False, wc) else
|
|
1603 | + ; if null solvers then return (False, simples1) else
|
|
1606 | 1604 | |
1607 | 1605 | do { given <- getInertGivens
|
1608 | 1606 | ; wanted <- TcS.zonkSimples simples1 -- Plugin requires zonked inputs
|
... | ... | @@ -1624,8 +1622,7 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1 }) |
1624 | 1622 | ; mapM_ setEv solved_wanted
|
1625 | 1623 | |
1626 | 1624 | ; traceTcS "Finished plugins }" (ppr new_wanted)
|
1627 | - ; return ( notNull (pluginNewCts p)
|
|
1628 | - , wc { wc_simple = all_new_wanted } ) } }
|
|
1625 | + ; return ( notNull (pluginNewCts p), all_new_wanted ) } }
|
|
1629 | 1626 | where
|
1630 | 1627 | setEv :: (EvTerm,Ct) -> TcS ()
|
1631 | 1628 | setEv (ev,ct) = case ctEvidence ct of
|
... | ... | @@ -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( WantedConstraints, Cts, Implication )
|
|
5 | +import GHC.Tc.Types.Constraint( Cts, Implication )
|
|
6 | 6 | |
7 | -solveSimpleWanteds :: Cts -> TcS WantedConstraints
|
|
7 | +solveSimpleWanteds :: Cts -> TcS Cts
|
|
8 | 8 | trySolveImplication :: Implication -> TcS Bool |
... | ... | @@ -509,8 +509,8 @@ data EvTerm |
509 | 509 | | EvFun -- /\as \ds. let binds in v
|
510 | 510 | { et_tvs :: [TyVar]
|
511 | 511 | , et_given :: [EvVar]
|
512 | - , et_binds :: TcEvBinds -- This field is why we need an EvFun
|
|
513 | - -- constructor, and can't just use EvExpr
|
|
512 | + , et_binds :: Bag EvBind -- This field is why we need an EvFun
|
|
513 | + -- constructor, and can't just use EvExpr
|
|
514 | 514 | , et_body :: EvVar }
|
515 | 515 | |
516 | 516 | deriving Data.Data
|
... | ... | @@ -876,7 +876,11 @@ relevantEvVar v = isInternalName (varName v) |
876 | 876 | evVarsOfTerm :: EvTerm -> VarSet
|
877 | 877 | evVarsOfTerm (EvExpr e) = exprSomeFreeVars relevantEvVar e
|
878 | 878 | evVarsOfTerm (EvTypeable _ ev) = evVarsOfTypeable ev
|
879 | -evVarsOfTerm (EvFun {}) = emptyVarSet -- See Note [Free vars of EvFun]
|
|
879 | +evVarsOfTerm (EvFun { et_tvs = tvs, et_given = given, et_binds = binds, et_body = v })
|
|
880 | + = fvs `delVarSetList` bndrs
|
|
881 | + where
|
|
882 | + fvs = foldr (unionVarSet . evVarsOfTerm . eb_rhs) (unitVarSet v) binds
|
|
883 | + bndrs = foldr ((:) . eb_lhs) (tvs ++ given) binds
|
|
880 | 884 | |
881 | 885 | evVarsOfTerms :: [EvTerm] -> VarSet
|
882 | 886 | evVarsOfTerms = mapUnionVarSet evVarsOfTerm
|
... | ... | @@ -1764,7 +1764,7 @@ zonkEvTerm (EvFun { et_tvs = tvs, et_given = evs |
1764 | 1764 | , et_binds = ev_binds, et_body = body_id })
|
1765 | 1765 | = runZonkBndrT (zonkTyBndrsX tvs) $ \ new_tvs ->
|
1766 | 1766 | runZonkBndrT (zonkEvBndrsX evs) $ \ new_evs ->
|
1767 | - runZonkBndrT (zonkTcEvBinds ev_binds) $ \ new_ev_binds ->
|
|
1767 | + runZonkBndrT (zonkEvBinds ev_binds) $ \ new_ev_binds ->
|
|
1768 | 1768 | do { new_body_id <- zonkIdOcc body_id
|
1769 | 1769 | ; return (EvFun { et_tvs = new_tvs, et_given = new_evs
|
1770 | 1770 | , et_binds = new_ev_binds, et_body = new_body_id }) }
|
... | ... | @@ -33,7 +33,7 @@ tried :: forall (e :: Type). (forall m. C1T e m) => e -> () |
33 | 33 | tried = try @e
|
34 | 34 | |
35 | 35 | -- From the call to "try", we get [W] D (T e).
|
36 | --- After using the instance for D, we get the QC [G] C3 m ==> [W] C1 (T e) m.
|
|
36 | +-- After using the instance for D, we get the QC [W] (forall m. C3 m ==> C1 (T e) m)
|
|
37 | 37 | --
|
38 | 38 | -- The Given "[G] C3 m" thus arises from superclass expansion
|
39 | 39 | -- from "D (T e)", which contains a type family application, T.
|
... | ... | @@ -41,3 +41,16 @@ tried = try @e |
41 | 41 | -- expanding the superclasses of C3 (in this case, C2); in particular
|
42 | 42 | -- ltPatersonSize needs to handle a type family in its second argument.
|
43 | 43 | |
44 | +{- [G] forall m. C1T e m
|
|
45 | + --> sc
|
|
46 | + [G] forall m. C1 (T e) m <<--- aJT
|
|
47 | + |
|
48 | + [W] D (T e)
|
|
49 | +--> instance
|
|
50 | + [W] (forall m. C3 m => C1 (T e) m)
|
|
51 | + |
|
52 | + ---- Implication: forall m2 ---
|
|
53 | + [G] C3 m2
|
|
54 | + [W] C1 (T e) m2
|
|
55 | + --> solve via qci
|
|
56 | +-} |