... |
... |
@@ -451,9 +451,14 @@ kickOutRewritable ko_spec new_fr |
451
|
451
|
, text "Residual inerts =" <+> ppr ics' ]) } }
|
452
|
452
|
|
453
|
453
|
kickOutAfterUnification :: [TcTyVar] -> TcS ()
|
454
|
|
-kickOutAfterUnification tv_list = case nonEmpty tv_list of
|
455
|
|
- Nothing -> return ()
|
456
|
|
- Just tvs -> do
|
|
454
|
+kickOutAfterUnification tv_list
|
|
455
|
+ = case nonEmpty tv_list of
|
|
456
|
+ Nothing -> return ()
|
|
457
|
+ Just tvs -> setUnificationFlagTo min_tv_lvl
|
|
458
|
+ where
|
|
459
|
+ min_tv_lvl = foldr1 minTcLevel (NE.map tcTyVarLevel tvs)
|
|
460
|
+
|
|
461
|
+{-
|
457
|
462
|
{ let tv_set = mkVarSet tv_list
|
458
|
463
|
|
459
|
464
|
; n_kicked <- kickOutRewritable (KOAfterUnify tv_set) (Given, NomEq)
|
... |
... |
@@ -469,6 +474,7 @@ kickOutAfterUnification tv_list = case nonEmpty tv_list of |
469
|
474
|
|
470
|
475
|
; traceTcS "kickOutAfterUnification" (ppr tvs $$ text "n_kicked =" <+> ppr n_kicked)
|
471
|
476
|
; return n_kicked }
|
|
477
|
+-}
|
472
|
478
|
|
473
|
479
|
kickOutAfterFillingCoercionHole :: CoercionHole -> TcS ()
|
474
|
480
|
-- See Wrinkle (URW2) in Note [Unify only if the rewriter set is empty]
|
... |
... |
@@ -1286,43 +1292,23 @@ tryTcS (TcS thing_inside) |
1286
|
1292
|
|
1287
|
1293
|
; return True } }
|
1288
|
1294
|
|
1289
|
|
-nestFunDepsTcS :: TcS a -> TcS Bool
|
|
1295
|
+nestFunDepsTcS :: TcS a -> TcS (Bool, a)
|
1290
|
1296
|
nestFunDepsTcS (TcS thing_inside)
|
1291
|
|
- = TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var
|
1292
|
|
- , tcs_unif_lvl = unif_lvl_var }) ->
|
|
1297
|
+ = reportUnifications $
|
|
1298
|
+ TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var }) ->
|
|
1299
|
+ TcM.pushTcLevelM_ $
|
|
1300
|
+ -- pushTcLevelTcM: increase the level so that unification variables
|
|
1301
|
+ -- allocated by the fundep-creation itself don't count as useful unifications
|
1293
|
1302
|
do { inerts <- TcM.readTcRef inerts_var
|
1294
|
1303
|
; new_inert_var <- TcM.newTcRef inerts
|
1295
|
1304
|
; new_wl_var <- TcM.newTcRef emptyWorkList
|
1296
|
|
- ; new_unif_lvl_var <- TcM.newTcRef Nothing
|
1297
|
1305
|
; let nest_env = env { tcs_inerts = new_inert_var
|
1298
|
|
- , tcs_worklist = new_wl_var
|
1299
|
|
- , tcs_unif_lvl = new_unif_lvl_var }
|
|
1306
|
+ , tcs_worklist = new_wl_var }
|
1300
|
1307
|
|
1301
|
1308
|
; TcM.traceTc "nestFunDepsTcS {" empty
|
1302
|
|
- ; (inner_lvl, _res) <- TcM.pushTcLevelM $
|
1303
|
|
- thing_inside nest_env
|
1304
|
|
- -- Increase the level so that unification variables allocated by
|
1305
|
|
- -- the fundep-creation itself don't count as useful unifications
|
|
1309
|
+ ; res <- thing_inside nest_env
|
1306
|
1310
|
; TcM.traceTc "nestFunDepsTcS }" empty
|
1307
|
|
-
|
1308
|
|
- -- Figure out whether the fundeps did any useful unifications,
|
1309
|
|
- -- and if so update the tcs_unif_lvl
|
1310
|
|
- ; mb_new_lvl <- TcM.readTcRef new_unif_lvl_var
|
1311
|
|
- ; case mb_new_lvl of
|
1312
|
|
- Just unif_lvl
|
1313
|
|
- | inner_lvl `deeperThanOrSame` unif_lvl
|
1314
|
|
- -> -- Some useful unifications took place
|
1315
|
|
- do { mb_old_lvl <- TcM.readTcRef unif_lvl_var
|
1316
|
|
- ; case mb_old_lvl of
|
1317
|
|
- Just old_lvl | unif_lvl `deeperThanOrSame` old_lvl
|
1318
|
|
- -> return ()
|
1319
|
|
- _ -> TcM.writeTcRef unif_lvl_var (Just unif_lvl)
|
1320
|
|
- ; return True }
|
1321
|
|
-
|
1322
|
|
- _ -> return False -- No unifications (except of vars
|
1323
|
|
- -- generated in the fundep stuff itself)
|
1324
|
|
- }
|
1325
|
|
-
|
|
1311
|
+ ; return res }
|
1326
|
1312
|
|
1327
|
1313
|
updateInertsWith :: InertSet -> InertSet -> InertSet
|
1328
|
1314
|
-- Update the current inert set with bits from a nested solve,
|
... |
... |
@@ -1403,30 +1389,6 @@ setTcEvBindsMap :: EvBindsVar -> EvBindMap -> TcS () |
1403
|
1389
|
setTcEvBindsMap ev_binds_var binds
|
1404
|
1390
|
= wrapTcS $ TcM.setTcEvBindsMap ev_binds_var binds
|
1405
|
1391
|
|
1406
|
|
-unifyTyVar :: TcTyVar -> TcType -> TcS ()
|
1407
|
|
--- Unify a meta-tyvar with a type
|
1408
|
|
--- We keep track of how many unifications have happened in tcs_unified,
|
1409
|
|
---
|
1410
|
|
--- We should never unify the same variable twice!
|
1411
|
|
-unifyTyVar tv ty
|
1412
|
|
- = assertPpr (isMetaTyVar tv) (ppr tv) $
|
1413
|
|
- TcS $ \ env ->
|
1414
|
|
- do { TcM.traceTc "unifyTyVar" (ppr tv <+> text ":=" <+> ppr ty)
|
1415
|
|
- ; TcM.liftZonkM $ TcM.writeMetaTyVar tv ty
|
1416
|
|
- ; TcM.updTcRef (tcs_unified env) (+1) }
|
1417
|
|
-
|
1418
|
|
-reportUnifications :: TcS a -> TcS (Int, a)
|
1419
|
|
--- Record how many unifications are done by thing_inside
|
1420
|
|
--- We could return a Bool instead of an Int;
|
1421
|
|
--- all that matters is whether it is no-zero
|
1422
|
|
-reportUnifications (TcS thing_inside)
|
1423
|
|
- = TcS $ \ env ->
|
1424
|
|
- do { inner_unified <- TcM.newTcRef 0
|
1425
|
|
- ; res <- thing_inside (env { tcs_unified = inner_unified })
|
1426
|
|
- ; n_unifs <- TcM.readTcRef inner_unified
|
1427
|
|
- ; TcM.updTcRef (tcs_unified env) (+ n_unifs)
|
1428
|
|
- ; return (n_unifs, res) }
|
1429
|
|
-
|
1430
|
1392
|
getDefaultInfo :: TcS (DefaultEnv, Bool)
|
1431
|
1393
|
getDefaultInfo = wrapTcS TcM.tcGetDefaultTys
|
1432
|
1394
|
|
... |
... |
@@ -1844,6 +1806,43 @@ produced the same Derived constraint.) |
1844
|
1806
|
-}
|
1845
|
1807
|
|
1846
|
1808
|
|
|
1809
|
+unifyTyVar :: TcTyVar -> TcType -> TcS ()
|
|
1810
|
+-- Unify a meta-tyvar with a type
|
|
1811
|
+-- We keep track of how many unifications have happened in tcs_unified,
|
|
1812
|
+--
|
|
1813
|
+-- We should never unify the same variable twice!
|
|
1814
|
+unifyTyVar tv ty
|
|
1815
|
+ = assertPpr (isMetaTyVar tv) (ppr tv) $
|
|
1816
|
+ do { liftZonkTcS (TcM.writeMetaTyVar tv ty) -- Produces a trace message
|
|
1817
|
+ ; setUnificationFlagTo (tcTyVarLevel tv) }
|
|
1818
|
+
|
|
1819
|
+reportUnifications :: TcS a -> TcS (Bool, a)
|
|
1820
|
+-- Record whether any unifications are done by thing_inside
|
|
1821
|
+-- Remember to propagate the information to the enclosing context
|
|
1822
|
+reportUnifications (TcS thing_inside)
|
|
1823
|
+ = TcS $ \ env@(TcSEnv { tcs_unif_lvl = outer_ul_var }) ->
|
|
1824
|
+ do { inner_ul_var <- TcM.newTcRef Nothing
|
|
1825
|
+
|
|
1826
|
+ ; res <- thing_inside (env { tcs_unif_lvl = inner_ul_var })
|
|
1827
|
+
|
|
1828
|
+ ; ambient_lvl <- TcM.getTcLevel
|
|
1829
|
+ ; mb_inner_lvl <- TcM.readTcRef inner_ul_var
|
|
1830
|
+
|
|
1831
|
+ ; case mb_inner_lvl of
|
|
1832
|
+ Just unif_lvl
|
|
1833
|
+ | ambient_lvl `deeperThanOrSame` unif_lvl
|
|
1834
|
+ -> -- Some useful unifications took place
|
|
1835
|
+ do { mb_outer_lvl <- TcM.readTcRef outer_ul_var
|
|
1836
|
+ ; case mb_outer_lvl of
|
|
1837
|
+ Just outer_unif_lvl | outer_unif_lvl `strictlyDeeperThan` unif_lvl
|
|
1838
|
+ -> -- Update, because outer_unif_lv > unif_lvl
|
|
1839
|
+ TcM.writeTcRef outer_ul_var (Just unif_lvl)
|
|
1840
|
+ _ -> return ()
|
|
1841
|
+ ; return (True, res) }
|
|
1842
|
+
|
|
1843
|
+ _ -> -- No useful unifications
|
|
1844
|
+ return (False, res) }
|
|
1845
|
+
|
1847
|
1846
|
getUnificationFlag :: TcS Bool
|
1848
|
1847
|
-- We are at ambient level i
|
1849
|
1848
|
-- If the unification flag = Just i, reset it to Nothing and return True
|
... |
... |
@@ -2226,7 +2225,7 @@ unifyForAllBody ev role unify_body |
2226
|
2225
|
= do { (res, cts, unified) <- wrapUnifierX ev role unify_body
|
2227
|
2226
|
|
2228
|
2227
|
-- Kick out any inert constraint that we have unified
|
2229
|
|
- ; _ <- kickOutAfterUnification unified
|
|
2228
|
+ ; kickOutAfterUnification unified
|
2230
|
2229
|
|
2231
|
2230
|
; return (res, cts) }
|
2232
|
2231
|
|
... |
... |
@@ -2255,7 +2254,7 @@ wrapUnifierTcS ev role do_unifications |
2255
|
2254
|
updWorkListTcS (extendWorkListChildEqs ev cts)
|
2256
|
2255
|
|
2257
|
2256
|
-- And kick out any inert constraint that we have unified
|
2258
|
|
- ; _ <- kickOutAfterUnification unified
|
|
2257
|
+ ; kickOutAfterUnification unified
|
2259
|
2258
|
|
2260
|
2259
|
; return (res, cts, unified) }
|
2261
|
2260
|
|