... |
... |
@@ -588,22 +588,24 @@ solving fails and we use the superclass of C: |
588
|
588
|
The moving parts are relatively simple:
|
589
|
589
|
|
590
|
590
|
* To attempt to solve the constraint completely, we just recursively
|
591
|
|
- call the constraint solver. See the use of `tryTcS` in
|
|
591
|
+ call the constraint solver. See the use of `tryShortCutTcS` in
|
592
|
592
|
`tcShortCutSolver`.
|
593
|
593
|
|
594
|
|
-* When this attempted recursive solving, we set a special mode
|
595
|
|
- `TcSShortCut`, which signals that we are trying to solve using only
|
596
|
|
- top-level instances. We switch on `TcSShortCut` mode in
|
597
|
|
- `tryShortCutSolver`.
|
|
594
|
+* When this attempted recursive solving, in `tryShortCutTcS`, we
|
|
595
|
+ - start with an empty inert set: no Givens and no Wanteds
|
|
596
|
+ - set a special mode `TcSShortCut`, which signals that we are trying to solve
|
|
597
|
+ using only top-level instances.
|
598
|
598
|
|
599
|
|
-* When in TcSShortCut mode, we behave specially in a few places:
|
600
|
|
- - `tryInertDicts`, where we would otherwise look for a Given to solve our Wanted
|
601
|
|
- - `GHC.Tc.Solver.Monad.lookupInertDict` similarly
|
602
|
|
- - `noMatchableGivenDicts`, which also consults the Givens
|
603
|
|
- - `matchLocalInst`, which would otherwise consult Given quantified constraints
|
604
|
|
- - `GHC.Tc.Solver.Instance.Class.matchInstEnv`: when short-cut solving, don't
|
605
|
|
- pick overlappable top-level instances
|
606
|
|
- - `GHC.Tc.Solver.Solve.runTcPluginsWanted`: don't pass any Givens to the plugin
|
|
599
|
+* When in TcSShortCut mode, since there are no Givens we can short-circuit;
|
|
600
|
+ these are all just optimisations:
|
|
601
|
+ - `tryInertDicts`
|
|
602
|
+ - `GHC.Tc.Solver.Monad.lookupInertDict`
|
|
603
|
+ - `noMatchableGivenDicts`
|
|
604
|
+ - `matchLocalInst`
|
|
605
|
+ - `GHC.Tc.Solver.Solve.runTcPluginsWanted`
|
|
606
|
+
|
|
607
|
+* In `GHC.Tc.Solver.Instance.Class.matchInstEnv`: when short-cut solving,
|
|
608
|
+ don't pick overlappable top-level instances
|
607
|
609
|
|
608
|
610
|
Some wrinkles:
|
609
|
611
|
|
... |
... |
@@ -770,14 +772,14 @@ tryInertDicts dict_ct |
770
|
772
|
|
771
|
773
|
try_inert_dicts :: TcSMode -> InertCans -> DictCt -> TcS (StopOrContinue ())
|
772
|
774
|
try_inert_dicts mode inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys })
|
773
|
|
- | not (mode == TcSShortCut) -- Ignore the inerts (esp Givens) in short-cut mode
|
774
|
|
- -- See Note [Shortcut solving]
|
|
775
|
+ | not (mode == TcSShortCut) -- Optimisation: ignore the inerts (esp Givens) in
|
|
776
|
+ -- short-cut mode. See Note [Shortcut solving]
|
775
|
777
|
, Just dict_i <- lookupInertDict inerts cls tys
|
776
|
778
|
, let ev_i = dictCtEvidence dict_i
|
777
|
779
|
loc_i = ctEvLoc ev_i
|
778
|
780
|
loc_w = ctEvLoc ev_w
|
779
|
781
|
= -- There is a matching dictionary in the inert set
|
780
|
|
- do { -- First to try to solve it /completely/ from top level instances
|
|
782
|
+ do { -- For a Wanted, first to try to solve it /completely/ from top level instances
|
781
|
783
|
-- See Note [Shortcut solving]
|
782
|
784
|
; short_cut_worked <- tryShortCutSolver (isGiven ev_i) dict_w
|
783
|
785
|
|
... |
... |
@@ -833,11 +835,7 @@ tryShortCutSolver try_short_cut dict_w@(DictCt { di_ev = ev_w }) |
833
|
835
|
, gopt Opt_SolveConstantDicts dflags
|
834
|
836
|
-- Enabled by the -fsolve-constant-dicts flag
|
835
|
837
|
|
836
|
|
- -> tryTcS $ -- tryTcS tries to completely solve some contraints
|
837
|
|
- -- Inherit the current solved_dicts, so that one invocation of
|
838
|
|
- -- tryShortCutSolver can benefit from the work of earlier invocations
|
839
|
|
- -- See wrinkle (SCS3) of Note [Shortcut solving]
|
840
|
|
- setTcSMode TcSShortCut $
|
|
838
|
+ -> tryShortCutTcS $ -- tryTcS tries to completely solve some contraints
|
841
|
839
|
do { residual <- solveSimpleWanteds (unitBag (CDictCan dict_w))
|
842
|
840
|
; return (isEmptyBag residual) }
|
843
|
841
|
|
... |
... |
@@ -977,7 +975,7 @@ matchClassInst dflags mode inerts clas tys loc |
977
|
975
|
noMatchableGivenDicts :: TcSMode -> InertSet -> CtLoc -> Class -> [TcType] -> Bool
|
978
|
976
|
noMatchableGivenDicts mode inerts@(IS { inert_cans = inert_cans }) loc_w clas tys
|
979
|
977
|
| TcSShortCut <- mode
|
980
|
|
- = True -- In TcSShortCut mode we behave as if there were no Givens at all
|
|
978
|
+ = True -- Optimisation: in TcSShortCut mode there are no Givens
|
981
|
979
|
| otherwise
|
982
|
980
|
= not $ anyBag matchable_given $
|
983
|
981
|
findDictsByClass (inert_dicts inert_cans) clas
|
... |
... |
@@ -1153,8 +1151,7 @@ matchLocalInst :: TcPredType -> CtLoc -> TcS ClsInstResult |
1153
|
1151
|
-- Look up the predicate in Given quantified constraints,
|
1154
|
1152
|
-- which are effectively just local instance declarations.
|
1155
|
1153
|
matchLocalInst body_pred loc
|
1156
|
|
- = do { -- In TcSShortCut mode we do not look at Givens;
|
1157
|
|
- -- c.f. tryInertDicts
|
|
1154
|
+ = do { -- Optimisation: in TcSShortCut mode there are no Givens (c.f. tryInertDicts)
|
1158
|
1155
|
mode <- getTcSMode
|
1159
|
1156
|
; case mode of
|
1160
|
1157
|
{ TcSShortCut -> do { traceTcS "matchLocalInst:TcSShortCut" (ppr body_pred)
|