| ... |
... |
@@ -36,6 +36,7 @@ import GHC.Types.Var.Set |
|
36
|
36
|
import GHC.Utils.Outputable
|
|
37
|
37
|
import GHC.Utils.Panic
|
|
38
|
38
|
|
|
|
39
|
+import Control.Monad( unless )
|
|
39
|
40
|
import GHC.Data.Pair
|
|
40
|
41
|
import Data.Maybe( isNothing, isJust, mapMaybe )
|
|
41
|
42
|
|
| ... |
... |
@@ -350,9 +351,9 @@ tryDictFunDepsLocal dict_ct@(DictCt { di_cls = cls, di_ev = work_ev }) |
|
350
|
351
|
| otherwise
|
|
351
|
352
|
= improveFromAnother (ctEvPred inert_ev) work_pred
|
|
352
|
353
|
|
|
353
|
|
-insolubleFunDep :: CtEvidence -> TcS (StopOrContinue ())
|
|
|
354
|
+insolubleFunDep :: CtEvidence -> TcS (StopOrContinue a)
|
|
354
|
355
|
-- The fundeps generated an insoluble constraint.
|
|
355
|
|
--- Stop solving with an (insoluble) CIrredCan
|
|
|
356
|
+-- Stop solving with an (insoluble) CIrredCan -- a bit like thowing an exception
|
|
356
|
357
|
-- It's valuable to flag such constraints as insoluble becuase that improves
|
|
357
|
358
|
-- pattern-match overlap checking
|
|
358
|
359
|
insolubleFunDep ev
|
| ... |
... |
@@ -495,16 +496,16 @@ tryFamEqFunDeps eqs_for_me fam_tc work_args |
|
495
|
496
|
= if isGiven ev
|
|
496
|
497
|
then tryGivenBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_item
|
|
497
|
498
|
else do { -- Note [Do local fundeps before top-level instances]
|
|
498
|
|
- tryFDEqns fam_tc work_args work_item $
|
|
499
|
|
- mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
|
|
|
499
|
+ eqns <- mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
|
|
|
500
|
+ ; tryFDEqns fam_tc work_args work_item eqns
|
|
500
|
501
|
|
|
501
|
|
- ; if hasRelevantGiven eqs_for_me work_args work_item
|
|
502
|
|
- ; then nopStage ()
|
|
503
|
|
- else tryFDEqns fam_tc work_args work_item $
|
|
504
|
|
- mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs }
|
|
|
502
|
+ ; unless (hasRelevantGiven eqs_for_me work_args work_item) $
|
|
|
503
|
+ do { eqns <- mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
|
|
|
504
|
+ ; tryFDEqns fam_tc work_args work_item eqns } }
|
|
505
|
505
|
|
|
506
|
|
- | isGiven ev -- See (INJFAM:Given)
|
|
507
|
|
- = nopStage ()
|
|
|
506
|
+-- | isGiven ev -- See (INJFAM:Given)
|
|
|
507
|
+-- = nopStage ()
|
|
|
508
|
+-- Continue even for Givens in the hope of discovering insolubility
|
|
508
|
509
|
|
|
509
|
510
|
-- Only Wanted constraints below here
|
|
510
|
511
|
|
| ... |
... |
@@ -512,24 +513,23 @@ tryFamEqFunDeps eqs_for_me fam_tc work_args |
|
512
|
513
|
= do { -- Note [Do local fundeps before top-level instances]
|
|
513
|
514
|
case tyConInjectivityInfo fam_tc of
|
|
514
|
515
|
NotInjective -> nopStage ()
|
|
515
|
|
- Injective inj -> tryFDEqns fam_tc work_args work_item $
|
|
516
|
|
- mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
|
|
|
516
|
+ Injective inj -> do { eqns <- mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
|
|
|
517
|
+ ; tryFDEqns fam_tc work_args work_item eqns }
|
|
517
|
518
|
|
|
518
|
|
- ; if hasRelevantGiven eqs_for_me work_args work_item
|
|
519
|
|
- then nopStage ()
|
|
520
|
|
- else tryFDEqns fam_tc work_args work_item $
|
|
521
|
|
- mkTopFamEqFDs fam_tc work_args work_rhs }
|
|
|
519
|
+ ; unless (hasRelevantGiven eqs_for_me work_args work_item) $
|
|
|
520
|
+ do { eqns <- mkTopFamEqFDs fam_tc work_args work_item
|
|
|
521
|
+ ; tryFDEqns fam_tc work_args work_item eqns } }
|
|
522
|
522
|
|
|
523
|
|
-mkTopFamEqFDs :: TyCon -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
524
|
|
-mkTopFamEqFDs fam_tc work_args work_rhs
|
|
|
523
|
+mkTopFamEqFDs :: TyCon -> [TcType] -> EqCt -> SolverStage [FunDepEqns]
|
|
|
524
|
+mkTopFamEqFDs fam_tc work_args work_item
|
|
525
|
525
|
| isOpenTypeFamilyTyCon fam_tc
|
|
526
|
526
|
, Injective inj_flags <- tyConInjectivityInfo fam_tc
|
|
527
|
527
|
= -- Open, injective type families
|
|
528
|
|
- mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
|
|
|
528
|
+ simpleStage (mkTopOpenFamEqFDs fam_tc inj_flags work_args work_item)
|
|
529
|
529
|
|
|
530
|
530
|
| Just ax <- isClosedFamilyTyCon_maybe fam_tc
|
|
531
|
531
|
= -- Closed type families
|
|
532
|
|
- mkTopClosedFamEqFDs ax work_args work_rhs
|
|
|
532
|
+ mkTopClosedFamEqFDs ax work_args work_item
|
|
533
|
533
|
|
|
534
|
534
|
| otherwise
|
|
535
|
535
|
= -- Data families, abstract families,
|
| ... |
... |
@@ -537,13 +537,13 @@ mkTopFamEqFDs fam_tc work_args work_rhs |
|
537
|
537
|
-- closed type families with no equations (isClosedFamilyTyCon_maybe returns Nothing)
|
|
538
|
538
|
return []
|
|
539
|
539
|
|
|
540
|
|
-tryFDEqns :: TyCon -> [TcType] -> EqCt -> TcS [FunDepEqns] -> SolverStage ()
|
|
541
|
|
-tryFDEqns fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) mk_fd_eqns
|
|
|
540
|
+tryFDEqns :: TyCon -> [TcType] -> EqCt -> [FunDepEqns] -> SolverStage ()
|
|
|
541
|
+tryFDEqns fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) fd_eqns
|
|
542
|
542
|
= Stage $
|
|
543
|
|
- do { fd_eqns <- mk_fd_eqns
|
|
544
|
|
- ; traceTcS "tryFDEqns" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr work_args
|
|
|
543
|
+ do { traceTcS "tryFDEqns" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr work_args
|
|
545
|
544
|
, text "rhs:" <+> ppr rhs
|
|
546
|
545
|
, text "eqns:" <+> ppr fd_eqns ])
|
|
|
546
|
+
|
|
547
|
547
|
; (insoluble, unif_happened) <- solveFunDeps ev fd_eqns
|
|
548
|
548
|
|
|
549
|
549
|
; if | unif_happened -> startAgainWith (CEqCan work_item)
|
| ... |
... |
@@ -553,17 +553,19 @@ tryFDEqns fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) mk_fd_eq |
|
553
|
553
|
-----------------------------------------
|
|
554
|
554
|
-- User-defined type families
|
|
555
|
555
|
-----------------------------------------
|
|
556
|
|
-mkTopClosedFamEqFDs :: CoAxiom Branched -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
|
556
|
+mkTopClosedFamEqFDs :: CoAxiom Branched -> [TcType] -> EqCt -> SolverStage [FunDepEqns]
|
|
557
|
557
|
-- Look at the top-level axioms; we effectively infer injectivity,
|
|
558
|
558
|
-- so we don't need tyConInjectivtyInfo. This works fine for closed
|
|
559
|
559
|
-- type families without injectivity info
|
|
560
|
560
|
-- See Note [Exploiting closed type families]
|
|
561
|
|
-mkTopClosedFamEqFDs ax work_args work_rhs
|
|
562
|
|
- = do { let branches = fromBranches (coAxiomBranches ax)
|
|
|
561
|
+mkTopClosedFamEqFDs ax work_args (EqCt { eq_ev = ev, eq_rhs = work_rhs })
|
|
|
562
|
+ = Stage $
|
|
|
563
|
+ do { let branches = fromBranches (coAxiomBranches ax)
|
|
563
|
564
|
; traceTcS "mkTopClosed" (ppr branches $$ ppr work_args $$ ppr work_rhs)
|
|
564
|
565
|
; case getRelevantBranches ax work_args work_rhs of
|
|
565
|
|
- [eqn] -> return [eqn] -- If there is just one relevant equation, use it
|
|
566
|
|
- _ -> return [] }
|
|
|
566
|
+ [] -> insolubleFunDep ev
|
|
|
567
|
+ [eqn] -> continueWith [eqn] -- If there is just one relevant equation, use it
|
|
|
568
|
+ _ -> continueWith [] }
|
|
567
|
569
|
|
|
568
|
570
|
hasRelevantGiven :: [EqCt] -> [TcType] -> EqCt -> Bool
|
|
569
|
571
|
-- A Given is relevant if it is not apart from the Wanted
|
| ... |
... |
@@ -606,9 +608,9 @@ getRelevantBranches ax work_args work_rhs |
|
606
|
608
|
no_match lhs_tys (CoAxBranch { cab_lhs = lhs_tys1 })
|
|
607
|
609
|
= isNothing (tcUnifyTysForInjectivity False lhs_tys1 lhs_tys)
|
|
608
|
610
|
|
|
609
|
|
-mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
|
611
|
+mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> EqCt -> TcS [FunDepEqns]
|
|
610
|
612
|
-- Implements (INJFAM:Wanted/top)
|
|
611
|
|
-mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
|
|
|
613
|
+mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs })
|
|
612
|
614
|
= do { fam_envs <- getFamInstEnvs
|
|
613
|
615
|
; let branches :: [CoAxBranch]
|
|
614
|
616
|
branches = concatMap (fromBranches . coAxiomBranches . fi_axiom) $
|
| ... |
... |
@@ -629,7 +631,7 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs |
|
629
|
631
|
| otherwise
|
|
630
|
632
|
= Nothing
|
|
631
|
633
|
|
|
632
|
|
-mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
|
634
|
+mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> SolverStage [FunDepEqns]
|
|
633
|
635
|
mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
|
|
634
|
636
|
= do { let -- eqns_from_inerts: see (INJFAM:Wanted/other)
|
|
635
|
637
|
eqns_from_inerts = mapMaybe do_one eqs_for_me
|
| ... |
... |
@@ -723,13 +725,13 @@ tryGivenBuiltinFamEqFDs eqs_for_me fam_tc ops work_args |
|
723
|
725
|
|
|
724
|
726
|
do_one _ = return ()
|
|
725
|
727
|
|
|
726
|
|
-mkTopBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
|
728
|
+mkTopBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> SolverStage [FunDepEqns]
|
|
727
|
729
|
mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
|
|
728
|
730
|
= return [FDEqns { fd_qtvs = []
|
|
729
|
731
|
, fd_eqs = map snd $ tryInteractTopFam ops fam_tc work_args work_rhs }]
|
|
730
|
732
|
|
|
731
|
733
|
mkLocalBuiltinFamEqFDs :: [EqCt] -> TyCon -> BuiltInSynFamily
|
|
732
|
|
- -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
|
734
|
+ -> [TcType] -> Xi -> SolverStage [FunDepEqns]
|
|
733
|
735
|
mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
|
|
734
|
736
|
= do { let do_one :: EqCt -> [FunDepEqns]
|
|
735
|
737
|
do_one (EqCt { eq_lhs = TyFamLHS _ inert_args, eq_rhs = inert_rhs })
|