Simon Peyton Jones pushed to branch wip/T26115 at Glasgow Haskell Compiler / GHC
Commits:
-
ff3f98d1
by Simon Peyton Jones at 2025-06-24T16:16:23+01:00
7 changed files:
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/Tc/Errors.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/Types/Evidence.hs
Changes:
| ... | ... | @@ -1181,8 +1181,8 @@ dsSpec_help poly_nm poly_id poly_rhs spec_inl orig_bndrs ds_call |
| 1181 | 1181 | |
| 1182 | 1182 | mk_spec_body fn_body = mkLets (rn_binds ++ picked_binds) $
|
| 1183 | 1183 | mkApps fn_body rule_lhs_args
|
| 1184 | - -- ToDo: not mkCoreApps! That uses exprType on fun which
|
|
| 1185 | - -- fails in specUnfolding, sigh
|
|
| 1184 | + -- NB: not mkCoreApps! That uses exprType on fun
|
|
| 1185 | + -- which fails in specUnfolding, sigh
|
|
| 1186 | 1186 | |
| 1187 | 1187 | poly_name = idName poly_id
|
| 1188 | 1188 | spec_occ = mkSpecOcc (getOccName poly_name)
|
| ... | ... | @@ -622,7 +622,8 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 622 | 622 | -- report2: we suppress these if there are insolubles elsewhere in the tree
|
| 623 | 623 | report2 = [ ("Implicit params", is_ip, False, mkGroupReporter mkIPErr)
|
| 624 | 624 | , ("Irreds", is_irred, False, mkGroupReporter mkIrredErr)
|
| 625 | - , ("Dicts", is_dict, False, mkGroupReporter mkDictErr) ]
|
|
| 625 | + , ("Dicts", is_dict, False, mkGroupReporter mkDictErr)
|
|
| 626 | + , ("Quantified", is_qc, False, mkGroupReporter mkQCErr) ]
|
|
| 626 | 627 | |
| 627 | 628 | -- report3: suppressed errors should be reported as categorized by either report1
|
| 628 | 629 | -- or report2. Keep this in sync with the suppress function above
|
| ... | ... | @@ -681,6 +682,9 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 681 | 682 | is_irred _ (IrredPred {}) = True
|
| 682 | 683 | is_irred _ _ = False
|
| 683 | 684 | |
| 685 | + is_qc _ (ForAllPred {}) = True
|
|
| 686 | + is_qc _ _ = False
|
|
| 687 | + |
|
| 684 | 688 | -- See situation (1) of Note [Suppressing confusing errors]
|
| 685 | 689 | is_ww_fundep item _ = is_ww_fundep_item item
|
| 686 | 690 | is_ww_fundep_item = isWantedWantedFunDepOrigin . errorItemOrigin
|
| ... | ... | @@ -2175,6 +2179,13 @@ Warn of loopy local equalities that were dropped. |
| 2175 | 2179 | ************************************************************************
|
| 2176 | 2180 | -}
|
| 2177 | 2181 | |
| 2182 | +mkQCErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
|
|
| 2183 | +mkQCErr ctxt items
|
|
| 2184 | + = do { let msg = mkPlainMismatchMsg $
|
|
| 2185 | + CouldNotDeduce (getUserGivens ctxt) items Nothing
|
|
| 2186 | + ; return $ important ctxt msg }
|
|
| 2187 | + |
|
| 2188 | + |
|
| 2178 | 2189 | mkDictErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
|
| 2179 | 2190 | mkDictErr ctxt orig_items
|
| 2180 | 2191 | = do { inst_envs <- tcGetInstEnvs
|
| ... | ... | @@ -2192,8 +2203,8 @@ mkDictErr ctxt orig_items |
| 2192 | 2203 | ; return $
|
| 2193 | 2204 | SolverReport
|
| 2194 | 2205 | { sr_important_msg = SolverReportWithCtxt ctxt err
|
| 2195 | - , sr_supplementary =
|
|
| 2196 | - [ SupplementaryImportErrors imps | imps <- maybeToList (NE.nonEmpty imp_errs) ]
|
|
| 2206 | + , sr_supplementary = [ SupplementaryImportErrors imps
|
|
| 2207 | + | imps <- maybeToList (NE.nonEmpty imp_errs) ]
|
|
| 2197 | 2208 | , sr_hints = hints
|
| 2198 | 2209 | }
|
| 2199 | 2210 | }
|
| ... | ... | @@ -701,7 +701,12 @@ and Given/instance fundeps entirely. |
| 701 | 701 | tryInertDicts :: DictCt -> SolverStage ()
|
| 702 | 702 | tryInertDicts dict_ct
|
| 703 | 703 | = Stage $ do { inerts <- getInertCans
|
| 704 | - ; try_inert_dicts inerts dict_ct }
|
|
| 704 | + ; mode <- getTcSMode
|
|
| 705 | + -- In TcSSpecPrag mode we do not look at Givens; that's the point
|
|
| 706 | + -- Looking at Wanteds would be OK but no real benefit
|
|
| 707 | + ; case mode of
|
|
| 708 | + TcSSpecPrag -> continueWith ()
|
|
| 709 | + _other -> try_inert_dicts inerts dict_ct }
|
|
| 705 | 710 | |
| 706 | 711 | try_inert_dicts :: InertCans -> DictCt -> TcS (StopOrContinue ())
|
| 707 | 712 | try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys })
|
| ... | ... | @@ -767,22 +772,15 @@ tryShortCutSolver try_short_cut dict_w@(DictCt { di_ev = ev_w }) |
| 767 | 772 | -- Enabled by the -fsolve-constant-dicts flag
|
| 768 | 773 | |
| 769 | 774 | -> tryTcS $ -- tryTcS tries to completely solve some contraints
|
| 775 | + -- Inherit the current solved_dicts, so that one invocation of
|
|
| 776 | + -- tryShortCutSolver can benefit from the work of earlier invocations
|
|
| 770 | 777 | setTcSMode TcSSpecPrag $
|
| 771 | - do { updInertSet zap_cans
|
|
| 772 | - ; solveSimpleWanteds (unitBag (CDictCan dict_w)) }
|
|
| 778 | + do { wc <- solveSimpleWanteds (unitBag (CDictCan dict_w))
|
|
| 779 | + ; return (isSolvedWC wc) }
|
|
| 773 | 780 | |
| 774 | 781 | | otherwise
|
| 775 | 782 | -> return False }
|
| 776 | 783 | |
| 777 | - where
|
|
| 778 | - zap_cans :: InertSet -> InertSet
|
|
| 779 | - -- Zap the inert Givens (so we don't try to use them for solving)
|
|
| 780 | - -- and any inert Wanteds (no harm but not much benefit either.
|
|
| 781 | - -- But preserve the current solved_dicts, so that one invocation of
|
|
| 782 | - -- tryShortCutSolver can benefit from the work of earlier invocations
|
|
| 783 | - zap_cans inerts@(IS { inert_cans = cans })
|
|
| 784 | - = inerts { inert_cans = emptyInertCans (inert_given_eq_lvl cans) }
|
|
| 785 | - |
|
| 786 | 784 | |
| 787 | 785 | {- *******************************************************************
|
| 788 | 786 | * *
|
| ... | ... | @@ -27,7 +27,6 @@ module GHC.Tc.Solver.InertSet ( |
| 27 | 27 | foldTyEqs, delEq, findEq,
|
| 28 | 28 | partitionInertEqs, partitionFunEqs,
|
| 29 | 29 | filterInertEqs, filterFunEqs,
|
| 30 | - inertGivens,
|
|
| 31 | 30 | foldFunEqs, addEqToCans,
|
| 32 | 31 | |
| 33 | 32 | -- * Inert Dicts
|
| ... | ... | @@ -347,6 +346,10 @@ data InertSet |
| 347 | 346 | -- Canonical Given, Wanted
|
| 348 | 347 | -- Sometimes called "the inert set"
|
| 349 | 348 | |
| 349 | + , inert_givens :: InertCans
|
|
| 350 | + -- A subset of inert_cans, containing only Givens
|
|
| 351 | + -- Used to initialise inert_cans when recursing inside implications
|
|
| 352 | + |
|
| 350 | 353 | , inert_cycle_breakers :: CycleBreakerVarStack
|
| 351 | 354 | |
| 352 | 355 | , inert_famapp_cache :: FunEqMap Reduction
|
| ... | ... | @@ -399,11 +402,14 @@ emptyInertCans given_eq_lvl |
| 399 | 402 | |
| 400 | 403 | emptyInertSet :: TcLevel -> InertSet
|
| 401 | 404 | emptyInertSet given_eq_lvl
|
| 402 | - = IS { inert_cans = emptyInertCans given_eq_lvl
|
|
| 405 | + = IS { inert_cans = empty_cans
|
|
| 406 | + , inert_givens = empty_cans
|
|
| 403 | 407 | , inert_cycle_breakers = emptyBag :| []
|
| 404 | 408 | , inert_famapp_cache = emptyFunEqs
|
| 405 | 409 | , inert_solved_dicts = emptyDictMap
|
| 406 | - , inert_safehask = emptyDictMap }
|
|
| 410 | + , inert_safehask = emptyDictMap }
|
|
| 411 | + where
|
|
| 412 | + empty_cans = emptyInertCans given_eq_lvl
|
|
| 407 | 413 | |
| 408 | 414 | {- Note [Solved dictionaries]
|
| 409 | 415 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2129,43 +2135,3 @@ Wrong! The level-check ensures that the inner implicit parameter wins. |
| 2129 | 2135 | that this chain of events won't happen, but that's very fragile.)
|
| 2130 | 2136 | -}
|
| 2131 | 2137 | |
| 2132 | -{- *********************************************************************
|
|
| 2133 | -* *
|
|
| 2134 | - Extracting Givens from the inert set
|
|
| 2135 | -* *
|
|
| 2136 | -********************************************************************* -}
|
|
| 2137 | - |
|
| 2138 | - |
|
| 2139 | --- | Extract only Given constraints from the inert set.
|
|
| 2140 | -inertGivens :: InertSet -> InertSet
|
|
| 2141 | -inertGivens is@(IS { inert_cans = cans, inert_safehask = safehask }) =
|
|
| 2142 | - is { inert_cans = givens_cans
|
|
| 2143 | - , inert_safehask = safehask_givens
|
|
| 2144 | - , inert_solved_dicts = emptyDictMap
|
|
| 2145 | - }
|
|
| 2146 | - where
|
|
| 2147 | - |
|
| 2148 | - isGivenEq :: EqCt -> Bool
|
|
| 2149 | - isGivenEq eq = isGiven (ctEvidence (CEqCan eq))
|
|
| 2150 | - isGivenDict :: DictCt -> Bool
|
|
| 2151 | - isGivenDict dict = isGiven (ctEvidence (CDictCan dict))
|
|
| 2152 | - isGivenIrred :: IrredCt -> Bool
|
|
| 2153 | - isGivenIrred irred = isGiven (ctEvidence (CIrredCan irred))
|
|
| 2154 | - |
|
| 2155 | - -- Filter the inert constraints for Givens
|
|
| 2156 | - (eq_givens_list, _) = partitionInertEqs isGivenEq (inert_eqs cans)
|
|
| 2157 | - (funeq_givens_list, _) = partitionFunEqs isGivenEq (inert_funeqs cans)
|
|
| 2158 | - dict_givens = filterDicts isGivenDict (inert_dicts cans)
|
|
| 2159 | - safehask_givens = filterDicts isGivenDict safehask
|
|
| 2160 | - irreds_givens = filterBag isGivenIrred (inert_irreds cans)
|
|
| 2161 | - |
|
| 2162 | - eq_givens = foldr addInertEqs emptyTyEqs eq_givens_list
|
|
| 2163 | - funeq_givens = foldr addFunEqs emptyFunEqs funeq_givens_list
|
|
| 2164 | - |
|
| 2165 | - givens_cans =
|
|
| 2166 | - cans
|
|
| 2167 | - { inert_eqs = eq_givens
|
|
| 2168 | - , inert_funeqs = funeq_givens
|
|
| 2169 | - , inert_dicts = dict_givens
|
|
| 2170 | - , inert_irreds = irreds_givens
|
|
| 2171 | - } |
| ... | ... | @@ -1293,27 +1293,21 @@ nestImplicTcS :: EvBindsVar |
| 1293 | 1293 | -> TcLevel -> TcS a
|
| 1294 | 1294 | -> TcS a
|
| 1295 | 1295 | nestImplicTcS ref inner_tclvl (TcS thing_inside)
|
| 1296 | - = TcS $ \ TcSEnv { tcs_unified = unified_var
|
|
| 1297 | - , tcs_inerts = old_inert_var
|
|
| 1298 | - , tcs_count = count
|
|
| 1299 | - , tcs_unif_lvl = unif_lvl
|
|
| 1300 | - , tcs_mode = mode
|
|
| 1301 | - } ->
|
|
| 1296 | + = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) ->
|
|
| 1302 | 1297 | do { inerts <- TcM.readTcRef old_inert_var
|
| 1298 | + |
|
| 1299 | + -- Initialise the inert_cans from the inert_givens of the parent
|
|
| 1300 | + -- so that the child is not polluted with the parent's inert Wanteds
|
|
| 1303 | 1301 | ; let nest_inert = inerts { inert_cycle_breakers = pushCycleBreakerVarStack
|
| 1304 | 1302 | (inert_cycle_breakers inerts)
|
| 1305 | - , inert_cans = (inert_cans inerts)
|
|
| 1303 | + , inert_cans = (inert_givens inerts)
|
|
| 1306 | 1304 | { inert_given_eqs = False } }
|
| 1307 | 1305 | -- All other InertSet fields are inherited
|
| 1308 | 1306 | ; new_inert_var <- TcM.newTcRef nest_inert
|
| 1309 | 1307 | ; new_wl_var <- TcM.newTcRef emptyWorkList
|
| 1310 | - ; let nest_env = TcSEnv { tcs_count = count -- Inherited
|
|
| 1311 | - , tcs_unif_lvl = unif_lvl -- Inherited
|
|
| 1312 | - , tcs_ev_binds = ref
|
|
| 1313 | - , tcs_unified = unified_var
|
|
| 1314 | - , tcs_inerts = new_inert_var
|
|
| 1315 | - , tcs_mode = mode
|
|
| 1316 | - , tcs_worklist = new_wl_var }
|
|
| 1308 | + ; let nest_env = env { tcs_ev_binds = ref
|
|
| 1309 | + , tcs_inerts = new_inert_var
|
|
| 1310 | + , tcs_worklist = new_wl_var }
|
|
| 1317 | 1311 | ; res <- TcM.setTcLevel inner_tclvl $
|
| 1318 | 1312 | thing_inside nest_env
|
| 1319 | 1313 | |
| ... | ... | @@ -1339,6 +1333,7 @@ nestTcS (TcS thing_inside) |
| 1339 | 1333 | ; new_wl_var <- TcM.newTcRef emptyWorkList
|
| 1340 | 1334 | ; let nest_env = env { tcs_inerts = new_inert_var
|
| 1341 | 1335 | , tcs_worklist = new_wl_var }
|
| 1336 | + -- Inherit tcs_ev_binds from caller
|
|
| 1342 | 1337 | |
| 1343 | 1338 | ; res <- thing_inside nest_env
|
| 1344 | 1339 | |
| ... | ... | @@ -1347,18 +1342,17 @@ nestTcS (TcS thing_inside) |
| 1347 | 1342 | |
| 1348 | 1343 | ; return res }
|
| 1349 | 1344 | |
| 1350 | -tryTcS :: TcS WantedConstraints -> TcS Bool
|
|
| 1345 | +tryTcS :: TcS Bool -> TcS Bool
|
|
| 1351 | 1346 | -- Like nestTcS, but
|
| 1352 | 1347 | -- (a) be a no-op if the nested computation returns Nothing
|
| 1353 | 1348 | -- (b) if (but only if) success, propagate nested bindings to the caller
|
| 1354 | 1349 | tryTcS (TcS thing_inside)
|
| 1355 | 1350 | = TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var
|
| 1356 | - , tcs_ev_binds = old_ev_binds_var
|
|
| 1357 | - , tcs_worklist = wl_var }) ->
|
|
| 1351 | + , tcs_ev_binds = old_ev_binds_var }) ->
|
|
| 1358 | 1352 | do { old_inerts <- TcM.readTcRef inerts_var
|
| 1359 | 1353 | ; new_inert_var <- TcM.newTcRef old_inerts
|
| 1360 | 1354 | ; new_wl_var <- TcM.newTcRef emptyWorkList
|
| 1361 | - ; new_ev_binds_var <- TcM.newTcEvBinds
|
|
| 1355 | + ; new_ev_binds_var <- TcM.cloneEvBindsVar old_ev_binds_var
|
|
| 1362 | 1356 | ; let nest_env = env { tcs_ev_binds = new_ev_binds_var
|
| 1363 | 1357 | , tcs_inerts = new_inert_var
|
| 1364 | 1358 | , tcs_worklist = new_wl_var }
|
| ... | ... | @@ -1367,10 +1361,10 @@ tryTcS (TcS thing_inside) |
| 1367 | 1361 | vcat [ text "old_ev_binds:" <+> ppr old_ev_binds_var
|
| 1368 | 1362 | , text "new_ev_binds:" <+> ppr new_ev_binds_var
|
| 1369 | 1363 | , ppr old_inerts ]
|
| 1370 | - ; wc <- thing_inside nest_env
|
|
| 1371 | - ; TcM.traceTc "tryTcS }" (ppr wc)
|
|
| 1364 | + ; solved <- thing_inside nest_env
|
|
| 1365 | + ; TcM.traceTc "tryTcS }" (ppr solved)
|
|
| 1372 | 1366 | |
| 1373 | - ; if not (isSolvedWC wc)
|
|
| 1367 | + ; if not solved
|
|
| 1374 | 1368 | then return False
|
| 1375 | 1369 | else do { -- Successfully solved
|
| 1376 | 1370 | -- Add the new bindings to the existing ones
|
| ... | ... | @@ -1382,17 +1376,12 @@ tryTcS (TcS thing_inside) |
| 1382 | 1376 | |
| 1383 | 1377 | ; TcM.traceTc "tryTcS update" (ppr (inert_solved_dicts new_inerts))
|
| 1384 | 1378 | |
| 1385 | - -- We **must not** drop solved implications, due
|
|
| 1386 | - -- to Note [Free vars of EvFun] in GHC.Tc.Types.Evidence;
|
|
| 1387 | - -- so we re-emit them here.
|
|
| 1388 | - ; TcM.updTcRef wl_var (extendWorkListImplics (wc_impl wc))
|
|
| 1389 | - |
|
| 1390 | 1379 | ; return True } }
|
| 1391 | 1380 | |
| 1392 | 1381 | updateInertsWith :: InertSet -> InertSet -> InertSet
|
| 1393 | 1382 | -- Update the current inert set with bits from a nested solve,
|
| 1394 | 1383 | -- that finished with a new inert set
|
| 1395 | --- In particular, propagage:
|
|
| 1384 | +-- In particular, propagate:
|
|
| 1396 | 1385 | -- - solved dictionaires; see Note [Propagate the solved dictionaries]
|
| 1397 | 1386 | -- - Safe Haskell failures
|
| 1398 | 1387 | updateInertsWith current_inerts
|
| ... | ... | @@ -280,6 +280,20 @@ solveNestedImplications implics |
| 280 | 280 | |
| 281 | 281 | ; return unsolved_implics }
|
| 282 | 282 | |
| 283 | +trySolveImplication :: Implication -> TcS Bool
|
|
| 284 | +trySolveImplication (Implic { ic_tclvl = tclvl
|
|
| 285 | + , ic_binds = ev_binds_var
|
|
| 286 | + , ic_given = given_ids
|
|
| 287 | + , ic_wanted = wanteds
|
|
| 288 | + , ic_env = ct_loc_env
|
|
| 289 | + , ic_info = info })
|
|
| 290 | + = nestImplicTcS ev_binds_var tclvl $
|
|
| 291 | + do { let loc = mkGivenLoc tclvl info ct_loc_env
|
|
| 292 | + givens = mkGivens loc given_ids
|
|
| 293 | + ; solveSimpleGivens givens
|
|
| 294 | + ; residual_wanted <- solveWanteds wanteds
|
|
| 295 | + ; return (isSolvedWC residual_wanted) }
|
|
| 296 | + |
|
| 283 | 297 | solveImplication :: Implication -- Wanted
|
| 284 | 298 | -> TcS Implication -- Simplified implication
|
| 285 | 299 | -- Precondition: The TcS monad contains an empty worklist and given-only inerts
|
| ... | ... | @@ -289,6 +303,7 @@ solveImplication imp@(Implic { ic_tclvl = tclvl |
| 289 | 303 | , ic_given = given_ids
|
| 290 | 304 | , ic_wanted = wanteds
|
| 291 | 305 | , ic_info = info
|
| 306 | + , ic_env = ct_loc_env
|
|
| 292 | 307 | , ic_status = status })
|
| 293 | 308 | | isSolvedStatus status
|
| 294 | 309 | = return imp -- Do nothing
|
| ... | ... | @@ -306,7 +321,7 @@ solveImplication imp@(Implic { ic_tclvl = tclvl |
| 306 | 321 | -- Solve the nested constraints
|
| 307 | 322 | ; (has_given_eqs, given_insols, residual_wanted)
|
| 308 | 323 | <- nestImplicTcS ev_binds_var tclvl $
|
| 309 | - do { let loc = mkGivenLoc tclvl info (ic_env imp)
|
|
| 324 | + do { let loc = mkGivenLoc tclvl info ct_loc_env
|
|
| 310 | 325 | givens = mkGivens loc given_ids
|
| 311 | 326 | ; solveSimpleGivens givens
|
| 312 | 327 | |
| ... | ... | @@ -958,6 +973,11 @@ solveSimpleGivens givens |
| 958 | 973 | | otherwise
|
| 959 | 974 | = do { traceTcS "solveSimpleGivens {" (ppr givens)
|
| 960 | 975 | ; go givens
|
| 976 | + |
|
| 977 | + -- Capture the Givens in the inert_givens of the inert set
|
|
| 978 | + -- for use by subsequent calls of nestImplicTcS
|
|
| 979 | + ; updInertSet (\is -> is { inert_givens = inert_cans is })
|
|
| 980 | + |
|
| 961 | 981 | ; traceTcS "End solveSimpleGivens }" empty }
|
| 962 | 982 | where
|
| 963 | 983 | go givens = do { solveSimples (listToBag givens)
|
| ... | ... | @@ -1348,7 +1368,7 @@ solveWantedForAll qci tvs theta body_pred |
| 1348 | 1368 | ; return ( wantedCtEvEvId wanted_ev
|
| 1349 | 1369 | , unitBag (mkNonCanonical $ CtWanted wanted_ev)) }
|
| 1350 | 1370 | |
| 1351 | - ; traceTcS "solveForAll" (ppr given_ev_vars $$ ppr wanteds $$ ppr w_id)
|
|
| 1371 | + ; traceTcS "solveForAll {" (ppr skol_tvs $$ ppr given_ev_vars $$ ppr wanteds $$ ppr w_id)
|
|
| 1352 | 1372 | ; ev_binds_var <- TcS.newTcEvBinds
|
| 1353 | 1373 | ; solved <- trySolveImplication $
|
| 1354 | 1374 | (implicationPrototype loc_env)
|
| ... | ... | @@ -1359,6 +1379,7 @@ solveWantedForAll qci tvs theta body_pred |
| 1359 | 1379 | , ic_skols = skol_tvs
|
| 1360 | 1380 | , ic_given = given_ev_vars
|
| 1361 | 1381 | , ic_wanted = emptyWC { wc_simple = wanteds } }
|
| 1382 | + ; traceTcS "sllveForAll }" (ppr solved)
|
|
| 1362 | 1383 | ; if not solved
|
| 1363 | 1384 | then do { addInertForAll qci
|
| 1364 | 1385 | ; stopWith (CtWanted wtd) "Wanted forall-constraint:unsolved" }
|
| ... | ... | @@ -1379,34 +1400,6 @@ solveWantedForAll qci tvs theta body_pred |
| 1379 | 1400 | ClassPred cls tys -> pSizeClassPred cls tys
|
| 1380 | 1401 | _ -> pSizeType pred
|
| 1381 | 1402 | |
| 1382 | -trySolveImplication :: Implication -> TcS Bool
|
|
| 1383 | -trySolveImplication imp
|
|
| 1384 | - = tryTcS $
|
|
| 1385 | - do { imp' <- solveImplication imp
|
|
| 1386 | - ; return (emptyWC { wc_impl = unitBag imp' }) }
|
|
| 1387 | - -- ToDo: this emptyWC bit is somewhat clumsy
|
|
| 1388 | - |
|
| 1389 | -{-
|
|
| 1390 | -solveWantedForAll_spec :: WantedCtEvidence -> TcS (StopOrContinue Void)
|
|
| 1391 | --- Solve this implication constraint completely or not at all
|
|
| 1392 | -solveWantedForAll_spec wtd
|
|
| 1393 | - = do { traceTcS "solveWantedForAll {" (ppr wtd)
|
|
| 1394 | - ; fully_solved <- tryTcS (setTcSMode TcSVanilla $
|
|
| 1395 | - solveWanteds (mkSimpleWC [ev]))
|
|
| 1396 | - -- It's crucial to call solveWanteds here, not solveSimpleWanteds,
|
|
| 1397 | - -- because solving `ev` will land in solveWantedForAll_norm,
|
|
| 1398 | - -- which emits an implication, which we must then solve
|
|
| 1399 | - ; if fully_solved
|
|
| 1400 | - then do { traceTcS "solveWantedForAll: fully solved }" (ppr wtd)
|
|
| 1401 | - ; return $ Stop ev (text "Fully solved:" <+> ppr wtd) }
|
|
| 1402 | - else do { traceTcS "solveWantedForAll: not fully solved }" (ppr wtd)
|
|
| 1403 | - ; updInertIrreds (IrredCt ev IrredShapeReason)
|
|
| 1404 | - -- Stash the unsolved quantified constraint in the irreds
|
|
| 1405 | - ; return $ Stop ev (text "Not fully solved:" <+> ppr wtd) } }
|
|
| 1406 | - where
|
|
| 1407 | - ev = CtWanted wtd
|
|
| 1408 | --}
|
|
| 1409 | - |
|
| 1410 | 1403 | {- Note [Solving a Wanted forall-constraint]
|
| 1411 | 1404 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1412 | 1405 | Solving a wanted forall (quantified) constraint
|
| ... | ... | @@ -894,7 +894,7 @@ evVarsOfTypeable ev = |
| 894 | 894 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 895 | 895 | Finding the free vars of an EvFun is made tricky by the fact the
|
| 896 | 896 | bindings et_binds may be a mutable variable. Fortunately, we
|
| 897 | -can just squeeze by. Here's how.
|
|
| 897 | +ocan just squeeze by. Here's how.
|
|
| 898 | 898 | |
| 899 | 899 | * evVarsOfTerm is used only by GHC.Tc.Solver.neededEvVars.
|
| 900 | 900 | * Each EvBindsVar in an et_binds field of an EvFun is /also/ in the
|