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 | +-} |