| ... |
... |
@@ -13,11 +13,11 @@ import {-# SOURCE #-} GHC.Tc.Solver.Solve( solveSimpleWanteds ) |
|
13
|
13
|
|
|
14
|
14
|
import GHC.Tc.Instance.FunDeps
|
|
15
|
15
|
import GHC.Tc.Solver.InertSet
|
|
16
|
|
-import GHC.Tc.Solver.Monad
|
|
17
|
16
|
import GHC.Tc.Solver.Types
|
|
|
17
|
+import GHC.Tc.Solver.Monad as TcS
|
|
|
18
|
+import GHC.Tc.Utils.Monad as TcM
|
|
18
|
19
|
import GHC.Tc.Utils.TcType
|
|
19
|
20
|
import GHC.Tc.Utils.Unify( UnifyEnv(..) )
|
|
20
|
|
-import GHC.Tc.Utils.Monad as TcM
|
|
21
|
21
|
import GHC.Tc.Types.Evidence
|
|
22
|
22
|
import GHC.Tc.Types.Constraint
|
|
23
|
23
|
|
| ... |
... |
@@ -39,7 +39,7 @@ import GHC.Utils.Panic |
|
39
|
39
|
import GHC.Utils.Misc( lengthExceeds )
|
|
40
|
40
|
|
|
41
|
41
|
import GHC.Data.Pair
|
|
42
|
|
-import Data.Maybe( isNothing, mapMaybe )
|
|
|
42
|
+import Data.Maybe( isNothing, isJust, mapMaybe )
|
|
43
|
43
|
|
|
44
|
44
|
|
|
45
|
45
|
{- Note [Overview of functional dependencies in type inference]
|
| ... |
... |
@@ -469,8 +469,8 @@ tryEqFunDeps work_item@(EqCt { eq_lhs = work_lhs |
|
469
|
469
|
, eq_eq_rel = eq_rel })
|
|
470
|
470
|
| NomEq <- eq_rel
|
|
471
|
471
|
, TyFamLHS fam_tc work_args <- work_lhs -- We have F args ~N# rhs
|
|
472
|
|
- = do { simpleStage $ traceTcS "tryEqFunDeps" (ppr work_item)
|
|
473
|
|
- ; eqs_for_me <- simpleStage $ getInertFamEqsFor fam_tc work_args work_rhs
|
|
|
472
|
+ = do { eqs_for_me <- simpleStage $ getInertFamEqsFor fam_tc work_args work_rhs
|
|
|
473
|
+ ; simpleStage $ traceTcS "tryEqFunDeps" (ppr work_item $$ ppr eqs_for_me)
|
|
474
|
474
|
; tryFamEqFunDeps eqs_for_me fam_tc work_args work_item }
|
|
475
|
475
|
| otherwise
|
|
476
|
476
|
= nopStage ()
|
| ... |
... |
@@ -485,10 +485,11 @@ tryFamEqFunDeps eqs_for_me fam_tc work_args |
|
485
|
485
|
else do { -- Note [Do local fundeps before top-level instances]
|
|
486
|
486
|
tryFDEqns fam_tc work_args work_item $
|
|
487
|
487
|
mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
|
|
488
|
|
- ; if all (isWanted . eqCtEvidence) eqs_for_me
|
|
489
|
|
- then tryFDEqns fam_tc work_args work_item $
|
|
490
|
|
- mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
|
|
491
|
|
- else nopStage () }
|
|
|
488
|
+
|
|
|
489
|
+ ; if hasRelevantGiven eqs_for_me work_args work_item
|
|
|
490
|
+ ; then nopStage ()
|
|
|
491
|
+ else tryFDEqns fam_tc work_args work_item $
|
|
|
492
|
+ mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs }
|
|
492
|
493
|
|
|
493
|
494
|
| isGiven ev -- See (INJFAM:Given)
|
|
494
|
495
|
= nopStage ()
|
| ... |
... |
@@ -502,10 +503,10 @@ tryFamEqFunDeps eqs_for_me fam_tc work_args |
|
502
|
503
|
Injective inj -> tryFDEqns fam_tc work_args work_item $
|
|
503
|
504
|
mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
|
|
504
|
505
|
|
|
505
|
|
- ; if all (isWanted . eqCtEvidence) eqs_for_me
|
|
506
|
|
- then tryFDEqns fam_tc work_args work_item $
|
|
507
|
|
- mkTopFamEqFDs fam_tc work_args work_rhs
|
|
508
|
|
- else nopStage () }
|
|
|
506
|
+ ; if hasRelevantGiven eqs_for_me work_args work_item
|
|
|
507
|
+ then nopStage ()
|
|
|
508
|
+ else tryFDEqns fam_tc work_args work_item $
|
|
|
509
|
+ mkTopFamEqFDs fam_tc work_args work_rhs }
|
|
509
|
510
|
|
|
510
|
511
|
mkTopFamEqFDs :: TyCon -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
511
|
512
|
mkTopFamEqFDs fam_tc work_args work_rhs
|
| ... |
... |
@@ -548,10 +549,8 @@ mkTopClosedFamEqFDs ax work_args work_rhs |
|
548
|
549
|
= do { let branches = fromBranches (coAxiomBranches ax)
|
|
549
|
550
|
; traceTcS "mkTopClosed" (ppr branches $$ ppr work_args $$ ppr work_rhs)
|
|
550
|
551
|
; case getRelevantBranches ax work_args work_rhs of
|
|
551
|
|
- [CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys, cab_rhs = rhs_ty }]
|
|
552
|
|
- -> return [FDEqns { fd_qtvs = qtvs
|
|
553
|
|
- , fd_eqs = zipWith Pair (rhs_ty:lhs_tys) (work_rhs:work_args) }]
|
|
554
|
|
- _ -> return [] }
|
|
|
552
|
+ [eqn] -> return [eqn]
|
|
|
553
|
+ _ -> return [] }
|
|
555
|
554
|
| otherwise
|
|
556
|
555
|
= return []
|
|
557
|
556
|
|
| ... |
... |
@@ -566,7 +565,21 @@ isInformativeType (TyConApp tc tys) = isGenerativeTyCon tc Nominal || |
|
566
|
565
|
tys `lengthExceeds` tyConArity tc
|
|
567
|
566
|
isInformativeType _ = True -- AppTy, ForAllTy, FunTy, LitTy
|
|
568
|
567
|
|
|
569
|
|
-getRelevantBranches :: CoAxiom Branched -> [TcType] -> Xi -> [CoAxBranch]
|
|
|
568
|
+hasRelevantGiven :: [EqCt] -> [TcType] -> EqCt -> Bool
|
|
|
569
|
+-- A Given is relevant if it is not apart from the Wanted
|
|
|
570
|
+hasRelevantGiven eqs_for_me work_args (EqCt { eq_rhs = work_rhs })
|
|
|
571
|
+ = any relevant eqs_for_me
|
|
|
572
|
+ where
|
|
|
573
|
+ work_tys = work_rhs : work_args
|
|
|
574
|
+
|
|
|
575
|
+ relevant (EqCt { eq_ev = ev, eq_lhs = lhs, eq_rhs = rhs_ty })
|
|
|
576
|
+ | isGiven ev
|
|
|
577
|
+ , TyFamLHS _ lhs_tys <- lhs
|
|
|
578
|
+ = isJust (tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys))
|
|
|
579
|
+ | otherwise
|
|
|
580
|
+ = False
|
|
|
581
|
+
|
|
|
582
|
+getRelevantBranches :: CoAxiom Branched -> [TcType] -> Xi -> [FunDepEqns]
|
|
570
|
583
|
getRelevantBranches ax work_args work_rhs
|
|
571
|
584
|
= go [] (fromBranches (coAxiomBranches ax))
|
|
572
|
585
|
where
|
| ... |
... |
@@ -574,13 +587,21 @@ getRelevantBranches ax work_args work_rhs |
|
574
|
587
|
|
|
575
|
588
|
go _ [] = []
|
|
576
|
589
|
go preceding (branch:branches)
|
|
577
|
|
- | is_relevant branch = branch : go (branch:preceding) branches
|
|
578
|
|
- | otherwise = go (branch:preceding) branches
|
|
|
590
|
+ = case is_relevant branch of
|
|
|
591
|
+ Just eqn -> eqn : go (branch:preceding) branches
|
|
|
592
|
+ Nothing -> go (branch:preceding) branches
|
|
579
|
593
|
where
|
|
580
|
|
- is_relevant (CoAxBranch { cab_lhs = lhs_tys, cab_rhs = rhs_ty })
|
|
581
|
|
- = case tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys) of
|
|
582
|
|
- Nothing -> False
|
|
583
|
|
- Just subst -> all (no_match (substTys subst lhs_tys)) preceding
|
|
|
594
|
+ is_relevant (CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys, cab_rhs = rhs_ty })
|
|
|
595
|
+ | Just subst <- tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys)
|
|
|
596
|
+ , let (subst', qtvs') = trim_qtvs subst qtvs
|
|
|
597
|
+ lhs_tys' = substTys subst' lhs_tys
|
|
|
598
|
+ rhs_ty' = substTy subst' rhs_ty
|
|
|
599
|
+ , all (no_match lhs_tys') preceding
|
|
|
600
|
+ = pprTrace "grb" (ppr qtvs $$ ppr subst $$ ppr qtvs' $$ ppr subst' $$ ppr lhs_tys $$ ppr lhs_tys') $
|
|
|
601
|
+ Just (FDEqns { fd_qtvs = qtvs'
|
|
|
602
|
+ , fd_eqs = zipWith Pair (rhs_ty':lhs_tys') work_tys })
|
|
|
603
|
+ | otherwise
|
|
|
604
|
+ = Nothing
|
|
584
|
605
|
|
|
585
|
606
|
no_match lhs_tys (CoAxBranch { cab_lhs = lhs_tys1 })
|
|
586
|
607
|
= isNothing (tcUnifyTysForInjectivity False lhs_tys1 lhs_tys)
|
| ... |
... |
@@ -608,15 +629,15 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs |
|
608
|
629
|
| otherwise
|
|
609
|
630
|
= Nothing
|
|
610
|
631
|
|
|
611
|
|
- trim_qtvs :: Subst -> [TcTyVar] -> (Subst,[TcTyVar])
|
|
612
|
|
- -- Tricky stuff: see (TIF1) in
|
|
613
|
|
- -- Note [Type inference for type families with injectivity]
|
|
614
|
|
- trim_qtvs subst [] = (subst, [])
|
|
615
|
|
- trim_qtvs subst (tv:tvs)
|
|
616
|
|
- | tv `elemSubst` subst = trim_qtvs subst tvs
|
|
617
|
|
- | otherwise = let !(subst1, tv') = substTyVarBndr subst tv
|
|
618
|
|
- !(subst', tvs') = trim_qtvs subst1 tvs
|
|
619
|
|
- in (subst', tv':tvs')
|
|
|
632
|
+trim_qtvs :: Subst -> [TcTyVar] -> (Subst,[TcTyVar])
|
|
|
633
|
+-- Tricky stuff: see (TIF1) in
|
|
|
634
|
+-- Note [Type inference for type families with injectivity]
|
|
|
635
|
+trim_qtvs subst [] = (subst, [])
|
|
|
636
|
+trim_qtvs subst (tv:tvs)
|
|
|
637
|
+ | tv `elemSubst` subst = trim_qtvs subst tvs
|
|
|
638
|
+ | otherwise = let !(subst1, tv') = substTyVarBndr subst tv
|
|
|
639
|
+ !(subst', tvs') = trim_qtvs subst1 tvs
|
|
|
640
|
+ in (subst', tv':tvs')
|
|
620
|
641
|
|
|
621
|
642
|
mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
|
|
622
|
643
|
mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
|
| ... |
... |
@@ -823,7 +844,7 @@ For /built-in/ type families, it's pretty similar, except that |
|
823
|
844
|
FDEqn { fd_qtvs = [b:kappa], fd_eqs = [ beta ~ Proxy @kappa b ] }
|
|
824
|
845
|
Notice that
|
|
825
|
846
|
* we must quantify the FunDepEqns over `b`, which is not matched; for this
|
|
826
|
|
- we will generate a fresh unfication variable in `instantiateFunDepEqn`.
|
|
|
847
|
+ we will generate a fresh unification variable in `instantiateFunDepEqn`.
|
|
827
|
848
|
* we must substitute `k:->kappa` in the kind of `b`.
|
|
828
|
849
|
This fancy footwork for `fd_qtvs` is done by `trim_qtvs` in
|
|
829
|
850
|
`mkInjWantedFamEqTopEqns`.
|
| ... |
... |
@@ -889,6 +910,10 @@ solveFunDeps work_ev fd_eqns |
|
889
|
910
|
= do { (unifs, _res)
|
|
890
|
911
|
<- reportFineGrainUnifications $
|
|
891
|
912
|
nestFunDepsTcS $
|
|
|
913
|
+ TcS.pushTcLevelM_ $
|
|
|
914
|
+ -- pushTcLevelTcM: increase the level so that unification variables
|
|
|
915
|
+ -- allocated by the fundep-creation itself don't count as useful unifications
|
|
|
916
|
+ -- See Note [Deeper TcLevel for partial improvement unification variables]
|
|
892
|
917
|
do { (_, eqs) <- wrapUnifier work_ev Nominal do_fundeps
|
|
893
|
918
|
; solveSimpleWanteds eqs }
|
|
894
|
919
|
-- Why solveSimpleWanteds? Answer
|