... |
... |
@@ -10,7 +10,7 @@ module GHC.Tc.Solver.Dict ( |
10
|
10
|
solveCallStack, -- For GHC.Tc.Solver
|
11
|
11
|
|
12
|
12
|
-- * Functional dependencies
|
13
|
|
- doTopFunDepImprovement, doLocalFunDepImprovement
|
|
13
|
+ doDictFunDepImprovement
|
14
|
14
|
) where
|
15
|
15
|
|
16
|
16
|
import GHC.Prelude
|
... |
... |
@@ -59,6 +59,7 @@ import GHC.Driver.DynFlags |
59
|
59
|
|
60
|
60
|
import qualified GHC.LanguageExtensions as LangExt
|
61
|
61
|
|
|
62
|
+import Data.Foldable( foldrM )
|
62
|
63
|
import Data.Maybe ( listToMaybe, mapMaybe, isJust )
|
63
|
64
|
import Data.Void( Void )
|
64
|
65
|
|
... |
... |
@@ -1630,92 +1631,93 @@ as the fundeps. |
1630
|
1631
|
#7875 is a case in point.
|
1631
|
1632
|
-}
|
1632
|
1633
|
|
1633
|
|
-doTopFunDepImprovement :: Bag DictCt -> TcS (Cts, Bool)
|
1634
|
|
--- (doFunDeps inst_envs cts)
|
|
1634
|
+doDictFunDepImprovement :: Cts -> TcS (Cts, Bool)
|
|
1635
|
+-- (doDictFunDepImprovement inst_envs cts)
|
1635
|
1636
|
-- * Generate the fundeps from interacting the
|
1636
|
1637
|
-- top-level `inst_envs` with the constraints `cts`
|
1637
|
1638
|
-- * Do the unifications and return any unsolved constraints
|
1638
|
1639
|
-- See Note [Fundeps with instances, and equality orientation]
|
1639
|
|
-doTopFunDepImprovement cts
|
1640
|
|
- = do { inst_envs <- getInstEnvs
|
1641
|
|
- ; do_dict_fundeps (do_one inst_envs) cts }
|
|
1640
|
+doDictFunDepImprovement unsolved_wanteds
|
|
1641
|
+ = do { inerts <- getInertCans -- The inert_dicts are all Givens
|
|
1642
|
+ ; inst_envs <- getInstEnvs
|
|
1643
|
+ ; (_, new_eqs, unifs) <- foldrM (do_one_dict inst_envs)
|
|
1644
|
+ (inert_dicts inerts, emptyBag, False)
|
|
1645
|
+ unsolved_wanteds
|
|
1646
|
+ ; return (new_eqs, unifs) }
|
|
1647
|
+
|
|
1648
|
+do_one_dict :: InstEnvs -> Ct
|
|
1649
|
+ -> (DictMap DictCt, Cts, Bool)
|
|
1650
|
+ -> TcS (DictMap DictCt, Cts, Bool)
|
|
1651
|
+do_one_dict inst_envs (CDictCan dict_ct) (local_dicts, new_eqs, unifs)
|
|
1652
|
+ = do { (new_eqs1, unifs1) <- do_one_top inst_envs dict_ct
|
|
1653
|
+ ; (local_dicts2, new_eqs2, unifs2) <- do_one_local local_dicts dict_ct
|
|
1654
|
+ ; return ( local_dicts2
|
|
1655
|
+ , new_eqs1 `unionBags` new_eqs2 `unionBags` new_eqs
|
|
1656
|
+ , unifs1 || unifs2 || unifs ) }
|
|
1657
|
+
|
|
1658
|
+do_one_dict _ _ acc -- Non-DictCt constraints
|
|
1659
|
+ = return acc
|
|
1660
|
+
|
|
1661
|
+do_one_top :: InstEnvs -> DictCt -> TcS (Cts, Bool)
|
|
1662
|
+do_one_top inst_envs (DictCt { di_ev = ev, di_cls = cls, di_tys = xis })
|
|
1663
|
+ = unifyFunDepWanteds ev eqns
|
1642
|
1664
|
where
|
1643
|
|
- do_one :: InstEnvs -> DictCt -> TcS (Cts, Bool)
|
1644
|
|
- do_one inst_envs (DictCt { di_ev = ev, di_cls = cls, di_tys = xis })
|
1645
|
|
- = unifyFunDepWanteds ev eqns
|
|
1665
|
+ eqns :: [FunDepEqn (CtLoc, RewriterSet)]
|
|
1666
|
+ eqns = improveFromInstEnv inst_envs mk_ct_loc cls xis
|
|
1667
|
+
|
|
1668
|
+ dict_pred = mkClassPred cls xis
|
|
1669
|
+ dict_loc = ctEvLoc ev
|
|
1670
|
+ dict_origin = ctLocOrigin dict_loc
|
|
1671
|
+ dict_rewriters = ctEvRewriters ev
|
|
1672
|
+
|
|
1673
|
+ mk_ct_loc :: ClsInst -- The instance decl
|
|
1674
|
+ -> (CtLoc, RewriterSet)
|
|
1675
|
+ mk_ct_loc ispec
|
|
1676
|
+ = (dict_loc { ctl_origin = new_orig }, dict_rewriters)
|
1646
|
1677
|
where
|
1647
|
|
- eqns :: [FunDepEqn (CtLoc, RewriterSet)]
|
1648
|
|
- eqns = improveFromInstEnv inst_envs mk_ct_loc cls xis
|
1649
|
|
-
|
1650
|
|
- dict_pred = mkClassPred cls xis
|
1651
|
|
- dict_loc = ctEvLoc ev
|
1652
|
|
- dict_origin = ctLocOrigin dict_loc
|
1653
|
|
- dict_rewriters = ctEvRewriters ev
|
1654
|
|
-
|
1655
|
|
- mk_ct_loc :: ClsInst -- The instance decl
|
1656
|
|
- -> (CtLoc, RewriterSet)
|
1657
|
|
- mk_ct_loc ispec
|
1658
|
|
- = (dict_loc { ctl_origin = new_orig }, dict_rewriters)
|
1659
|
|
- where
|
1660
|
|
- inst_pred = mkClassPred cls (is_tys ispec)
|
1661
|
|
- inst_loc = getSrcSpan (is_dfun ispec)
|
1662
|
|
- new_orig = FunDepOrigin2 dict_pred dict_origin
|
1663
|
|
- inst_pred inst_loc
|
1664
|
|
-
|
1665
|
|
-doLocalFunDepImprovement :: Bag DictCt -> TcS (Cts,Bool)
|
|
1678
|
+ inst_pred = mkClassPred cls (is_tys ispec)
|
|
1679
|
+ inst_loc = getSrcSpan (is_dfun ispec)
|
|
1680
|
+ new_orig = FunDepOrigin2 dict_pred dict_origin
|
|
1681
|
+ inst_pred inst_loc
|
|
1682
|
+
|
|
1683
|
+do_one_local :: DictMap DictCt -> DictCt -> TcS (DictMap DictCt, Cts, Bool)
|
1666
|
1684
|
-- Using functional dependencies, interact the unsolved Wanteds
|
1667
|
1685
|
-- against each other and the inert Givens, to produce new equalities
|
1668
|
|
-doLocalFunDepImprovement wanted
|
1669
|
|
- = do { inerts <- getInertCans -- The inert_dicts are all Givens
|
1670
|
|
- ; let all_dicts :: DictMap DictCt -- Both Givens and Wanteds
|
1671
|
|
- all_dicts = foldr addDict (inert_dicts inerts) wanted
|
1672
|
|
- ; do_dict_fundeps (do_one all_dicts) wanted }
|
|
1686
|
+do_one_local locals dict_ct@(DictCt { di_cls = cls, di_ev = wanted_ev })
|
|
1687
|
+ -- locals contains all the Givens and earlier Wanteds
|
|
1688
|
+ = do { (new_eqs, unifs) <- foldrM do_interaction (emptyBag, False) $
|
|
1689
|
+ findDictsByClass locals cls
|
|
1690
|
+ ; return (addDict dict_ct locals, new_eqs, unifs) }
|
1673
|
1691
|
where
|
1674
|
|
- -- all_dicts are all the Givens and all the Wanteds
|
1675
|
|
- do_one all_dicts (DictCt { di_cls = cls, di_ev = wanted_ev })
|
1676
|
|
- = do_dict_fundeps do_interaction (findDictsByClass all_dicts cls)
|
|
1692
|
+ wanted_pred = ctEvPred wanted_ev
|
|
1693
|
+ wanted_loc = ctEvLoc wanted_ev
|
|
1694
|
+
|
|
1695
|
+ do_interaction :: DictCt -> (Cts,Bool) -> TcS (Cts,Bool)
|
|
1696
|
+ do_interaction (DictCt { di_ev = all_ev }) (new_eqs, unifs) -- This can be Given or Wanted
|
|
1697
|
+ = do { traceTcS "doLocalFunDepImprovement" $
|
|
1698
|
+ vcat [ ppr wanted_ev
|
|
1699
|
+ , pprCtLoc wanted_loc, ppr (isGivenLoc wanted_loc)
|
|
1700
|
+ , pprCtLoc all_loc, ppr (isGivenLoc all_loc)
|
|
1701
|
+ , pprCtLoc deriv_loc, ppr (isGivenLoc deriv_loc) ]
|
|
1702
|
+
|
|
1703
|
+ ; (new_eqs1, unifs1) <- unifyFunDepWanteds wanted_ev $
|
|
1704
|
+ improveFromAnother (deriv_loc, all_rewriters)
|
|
1705
|
+ all_pred wanted_pred
|
|
1706
|
+ ; return (new_eqs1 `unionBags` new_eqs, unifs1 || unifs) }
|
1677
|
1707
|
where
|
1678
|
|
- wanted_pred = ctEvPred wanted_ev
|
1679
|
|
- wanted_loc = ctEvLoc wanted_ev
|
1680
|
|
-
|
1681
|
|
- do_interaction :: DictCt -> TcS (Cts,Bool)
|
1682
|
|
- do_interaction (DictCt { di_ev = all_ev }) -- This can be Given or Wanted
|
1683
|
|
- = do { traceTcS "doLocalFunDepImprovement" $
|
1684
|
|
- vcat [ ppr wanted_ev
|
1685
|
|
- , pprCtLoc wanted_loc, ppr (isGivenLoc wanted_loc)
|
1686
|
|
- , pprCtLoc all_loc, ppr (isGivenLoc all_loc)
|
1687
|
|
- , pprCtLoc deriv_loc, ppr (isGivenLoc deriv_loc) ]
|
1688
|
|
-
|
1689
|
|
- ; unifyFunDepWanteds wanted_ev $
|
1690
|
|
- improveFromAnother (deriv_loc, all_rewriters)
|
1691
|
|
- all_pred wanted_pred }
|
1692
|
|
- where
|
1693
|
|
- all_pred = ctEvPred all_ev
|
1694
|
|
- all_loc = ctEvLoc all_ev
|
1695
|
|
- all_rewriters = ctEvRewriters all_ev
|
1696
|
|
- deriv_loc = wanted_loc { ctl_depth = deriv_depth
|
1697
|
|
- , ctl_origin = deriv_origin }
|
1698
|
|
- deriv_depth = ctl_depth wanted_loc `maxSubGoalDepth`
|
1699
|
|
- ctl_depth all_loc
|
1700
|
|
- deriv_origin = FunDepOrigin1 wanted_pred
|
1701
|
|
- (ctLocOrigin wanted_loc)
|
1702
|
|
- (ctLocSpan wanted_loc)
|
1703
|
|
- all_pred
|
1704
|
|
- (ctLocOrigin all_loc)
|
1705
|
|
- (ctLocSpan all_loc)
|
1706
|
|
-
|
1707
|
|
-do_dict_fundeps :: (DictCt -> TcS (Cts,Bool)) -> Bag DictCt -> TcS (Cts,Bool)
|
1708
|
|
-do_dict_fundeps do_dict_fundep cts
|
1709
|
|
- = foldr do_one (return (emptyBag, False)) cts
|
1710
|
|
- where
|
1711
|
|
- do_one :: DictCt -> TcS (Cts,Bool) -> TcS (Cts,Bool)
|
1712
|
|
- do_one dict_ct do_rest
|
1713
|
|
- = -- assert (not (isGiven (dictCtEvidence dict_ct)) $
|
1714
|
|
- do { (cts1, unifs1) <- do_dict_fundep dict_ct
|
1715
|
|
- ; if isEmptyBag cts1 && not unifs1
|
1716
|
|
- then do_rest -- Common case
|
1717
|
|
- else do { (cts2, unifs2) <- do_rest
|
1718
|
|
- ; return (cts1 `unionBags` cts2, unifs1 || unifs2) } }
|
|
1708
|
+ all_pred = ctEvPred all_ev
|
|
1709
|
+ all_loc = ctEvLoc all_ev
|
|
1710
|
+ all_rewriters = ctEvRewriters all_ev
|
|
1711
|
+ deriv_loc = wanted_loc { ctl_depth = deriv_depth
|
|
1712
|
+ , ctl_origin = deriv_origin }
|
|
1713
|
+ deriv_depth = ctl_depth wanted_loc `maxSubGoalDepth`
|
|
1714
|
+ ctl_depth all_loc
|
|
1715
|
+ deriv_origin = FunDepOrigin1 wanted_pred
|
|
1716
|
+ (ctLocOrigin wanted_loc)
|
|
1717
|
+ (ctLocSpan wanted_loc)
|
|
1718
|
+ all_pred
|
|
1719
|
+ (ctLocOrigin all_loc)
|
|
1720
|
+ (ctLocSpan all_loc)
|
1719
|
1721
|
|
1720
|
1722
|
|
1721
|
1723
|
{- *********************************************************************
|