Simon Peyton Jones pushed to branch wip/T23162-part2 at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • compiler/GHC/Tc/Solver/FunDeps.hs
    ... ... @@ -25,7 +25,7 @@ import GHC.Core.FamInstEnv
    25 25
     import GHC.Core.Coercion
    
    26 26
     import GHC.Core.Predicate( EqRel(..) )
    
    27 27
     import GHC.Core.TyCon
    
    28
    -import GHC.Core.Unify( tcUnifyTyForInjectivity, typeListsAreApart, typesAreApart )
    
    28
    +import GHC.Core.Unify( tcUnifyTyForInjectivity, typeListsAreApart )
    
    29 29
     import GHC.Core.Coercion.Axiom
    
    30 30
     import GHC.Core.TyCo.Subst( elemSubst )
    
    31 31
     
    
    ... ... @@ -251,7 +251,7 @@ Consider T4254b:
    251 251
       it doesn't matter which of the two we pick, but historically we have
    
    252 252
       picked the local-fundeps first.
    
    253 253
     
    
    254
    -  #14745 is another example
    
    254
    +  #14745 is another example. And #13651.
    
    255 255
     
    
    256 256
     (DFL2) Try solving from top-level instances before fundeps.
    
    257 257
       From the definition `foo = op` we get
    
    ... ... @@ -259,7 +259,7 @@ Consider T4254b:
    259 259
         [W] FD Int Bool
    
    260 260
       We solve this from the top level instance before even trying fundeps.
    
    261 261
       If we did try fundeps, we'd generate [W] b ~ Bool, which fails.
    
    262
    -  That doesn't matter -- failing fundep equalties are discarded -- but it's
    
    262
    +  That doesn't matter -- failing fundep equalities are discarded -- but it's
    
    263 263
       a waste of effort.
    
    264 264
     
    
    265 265
       (DFL2) is achieved by trying fundeps only on /unsolved/ Wanteds.
    
    ... ... @@ -463,24 +463,30 @@ by the extensive code in GHC.Builtin.Types.Literals.
    463 463
     -}
    
    464 464
     
    
    465 465
     tryEqFunDeps :: EqCt -> SolverStage ()
    
    466
    -tryEqFunDeps work_item@(EqCt { eq_lhs = lhs, eq_eq_rel = eq_rel })
    
    466
    +tryEqFunDeps work_item@(EqCt { eq_lhs = work_lhs
    
    467
    +                             , eq_rhs = work_rhs
    
    468
    +                             , eq_eq_rel = eq_rel })
    
    467 469
       | NomEq <- eq_rel
    
    468
    -  , TyFamLHS tc args <- lhs
    
    469
    -  = tryFamEqFunDeps tc args work_item   -- We have F args ~ rhs
    
    470
    +  , TyFamLHS fam_tc work_args <- work_lhs     -- We have F args ~N# rhs
    
    471
    +  = do { eqs_for_me <- simpleStage$ getInertFamEqsFor fam_tc work_args work_rhs
    
    472
    +       ; tryFamEqFunDeps eqs_for_me fam_tc work_args work_item }
    
    470 473
       | otherwise
    
    471 474
       = nopStage ()
    
    472 475
     
    
    473 476
     
    
    474
    -tryFamEqFunDeps :: TyCon -> [TcType] -> EqCt -> SolverStage ()
    
    475
    -tryFamEqFunDeps fam_tc args work_item@(EqCt { eq_ev = ev, eq_rhs = rhs })
    
    477
    +tryFamEqFunDeps :: [EqCt] -> TyCon -> [TcType] -> EqCt -> SolverStage ()
    
    478
    +tryFamEqFunDeps eqs_for_me fam_tc work_args
    
    479
    +                work_item@(EqCt { eq_ev = ev, eq_rhs = work_rhs })
    
    476 480
       | Just ops <- isBuiltInSynFamTyCon_maybe fam_tc
    
    477 481
       = if isGiven ev
    
    478
    -    then tryGivenBuiltinFamEqFDs  fam_tc ops args work_item
    
    482
    +    then tryGivenBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_item
    
    479 483
         else do { -- Note [Do local fundeps before top-level instances]
    
    480
    -              tryFDEqns fam_tc args work_item $
    
    481
    -              mkLocalBuiltinFamEqFDs fam_tc ops args rhs
    
    482
    -            ; tryFDEqns fam_tc args work_item $
    
    483
    -              mkTopBuiltinFamEqFDs fam_tc ops args rhs }
    
    484
    +              tryFDEqns fam_tc work_args work_item $
    
    485
    +              mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
    
    486
    +            ; if null eqs_for_me
    
    487
    +              then tryFDEqns fam_tc work_args work_item $
    
    488
    +                   mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
    
    489
    +              else nopStage () }
    
    484 490
     
    
    485 491
       | isGiven ev    -- See (INJFAM:Given)
    
    486 492
       = nopStage ()
    
    ... ... @@ -491,26 +497,31 @@ tryFamEqFunDeps fam_tc args work_item@(EqCt { eq_ev = ev, eq_rhs = rhs })
    491 497
       , Injective inj_flags <- tyConInjectivityInfo fam_tc
    
    492 498
       = -- Open, injective type families
    
    493 499
         do { -- Note [Do local fundeps before top-level instances]
    
    494
    -         tryFDEqns fam_tc args work_item $
    
    495
    -         mkLocalUserFamEqFDs fam_tc inj_flags args rhs
    
    500
    +         tryFDEqns fam_tc work_args work_item $
    
    501
    +         mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
    
    496 502
     
    
    497
    -       ; tryFDEqns fam_tc args work_item $
    
    498
    -         mkTopOpenFamEqFDs fam_tc inj_flags args rhs }
    
    503
    +       ; if null eqs_for_me
    
    504
    +         then tryFDEqns fam_tc work_args work_item $
    
    505
    +              mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
    
    506
    +         else nopStage () }
    
    499 507
     
    
    500 508
       | Just ax <- isClosedFamilyTyCon_maybe fam_tc
    
    501 509
       = -- Closed type families
    
    502 510
         do { -- Note [Do local fundeps before top-level instances]
    
    503 511
              simpleStage $ traceTcS "fundep closed" (ppr fam_tc)
    
    512
    +
    
    504 513
            ; case tyConInjectivityInfo fam_tc of
    
    505 514
                NotInjective  -> nopStage()
    
    506
    -           Injective inj -> tryFDEqns fam_tc args work_item $
    
    507
    -                            mkLocalUserFamEqFDs fam_tc inj args rhs
    
    515
    +           Injective inj -> tryFDEqns fam_tc work_args work_item $
    
    516
    +                            mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
    
    508 517
     
    
    509 518
            -- Now look at the top-level axioms; we effectively infer injectivity,
    
    510 519
            -- so we don't need tyConInjectivtyInfo.  This works fine for closed
    
    511 520
            -- type families without injectivity info
    
    512
    -       ; tryFDEqns fam_tc args work_item $
    
    513
    -         mkTopClosedFamEqFDs ax args rhs }
    
    521
    +       ; if null eqs_for_me
    
    522
    +         then tryFDEqns fam_tc work_args work_item $
    
    523
    +              mkTopClosedFamEqFDs ax work_args work_rhs
    
    524
    +         else nopStage () }
    
    514 525
     
    
    515 526
       | otherwise -- Data families, abstract families
    
    516 527
       = nopStage ()
    
    ... ... @@ -542,7 +553,7 @@ mkTopClosedFamEqFDs ax work_args work_rhs
    542 553
         go (branch : later_branches)
    
    543 554
           | CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys
    
    544 555
                        , cab_rhs = rhs_ty, cab_incomps = incomps } <- branch
    
    545
    -      , not (no_match lhs_tys rhs_ty)
    
    556
    +      , not (eqnIsApart lhs_tys rhs_ty work_args work_rhs)
    
    546 557
           = if all no_match_branch incomps && all no_match_branch later_branches
    
    547 558
             then [FDEqns { fd_qtvs = qtvs, fd_eqs = zipWith Pair lhs_tys work_args }]
    
    548 559
             else []
    
    ... ... @@ -551,10 +562,7 @@ mkTopClosedFamEqFDs ax work_args work_rhs
    551 562
           = go later_branches
    
    552 563
     
    
    553 564
         no_match_branch (CoAxBranch { cab_lhs = lhs_tys, cab_rhs = rhs_ty })
    
    554
    -      = no_match lhs_tys rhs_ty
    
    555
    -
    
    556
    -    no_match lhs_tys rhs_ty = work_args `typeListsAreApart` lhs_tys ||
    
    557
    -                              work_rhs  `typesAreApart`     rhs_ty
    
    565
    +      = eqnIsApart lhs_tys rhs_ty work_args work_rhs
    
    558 566
     
    
    559 567
     mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    560 568
     -- Implements (INJFAM:Wanted/top)
    
    ... ... @@ -592,12 +600,10 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
    592 600
                                        !(subst', tvs') = trim_qtvs subst1 tvs
    
    593 601
                                    in (subst', tv':tvs')
    
    594 602
     
    
    595
    -mkLocalUserFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    596
    -mkLocalUserFamEqFDs fam_tc inj_flags work_args work_rhs
    
    597
    -  = do { fun_eqs_for_me <- getInertFamEqsFor fam_tc
    
    598
    -
    
    599
    -       ; let -- eqns_from_inerts: see (INJFAM:Wanted/other)
    
    600
    -             eqns_from_inerts = mapMaybe do_one fun_eqs_for_me
    
    603
    +mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    604
    +mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
    
    605
    +  = do { let -- eqns_from_inerts: see (INJFAM:Wanted/other)
    
    606
    +             eqns_from_inerts = mapMaybe do_one eqs_for_me
    
    601 607
                  -- eqns_from_self: see (INJFAM:Wanted/Self)
    
    602 608
                  eqns_from_self   = case tcSplitTyConApp_maybe work_rhs of
    
    603 609
                                       Just (tc,rhs_tys) | tc==fam_tc -> [mk_eqn rhs_tys]
    
    ... ... @@ -617,14 +623,16 @@ mkLocalUserFamEqFDs fam_tc inj_flags work_args work_rhs
    617 623
     --  Built-in type families
    
    618 624
     -----------------------------------------
    
    619 625
     
    
    620
    -tryGivenBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> EqCt -> SolverStage ()
    
    626
    +tryGivenBuiltinFamEqFDs :: [EqCt] -> TyCon -> BuiltInSynFamily
    
    627
    +                        -> [TcType] -> EqCt -> SolverStage ()
    
    621 628
     -- TyCon is definitely a built-in type family
    
    622 629
     -- Built-in type families are special becase we can generate
    
    623 630
     -- evidence from /Givens/. For example:
    
    624 631
     --    from [G] x+4~7 we can deduce [G] x~7
    
    625 632
     -- That's important!
    
    626 633
     -- See Note [Given/Given fundeps for built-in type families]
    
    627
    -tryGivenBuiltinFamEqFDs fam_tc ops work_args (EqCt { eq_ev = work_ev, eq_rhs = work_rhs })
    
    634
    +tryGivenBuiltinFamEqFDs eqs_for_me fam_tc ops work_args
    
    635
    +                        (EqCt { eq_ev = work_ev, eq_rhs = work_rhs })
    
    628 636
       = Stage $
    
    629 637
         do { traceTcS "tryBuiltinFamEqFDs" $
    
    630 638
              vcat [ text "lhs:" <+> ppr fam_tc <+> ppr work_args
    
    ... ... @@ -632,8 +640,7 @@ tryGivenBuiltinFamEqFDs fam_tc ops work_args (EqCt { eq_ev = work_ev, eq_rhs = w
    632 640
                   , text "work_ev:" <+> ppr work_ev ]
    
    633 641
     
    
    634 642
            -- interact with inert Givens, emitting new Givens
    
    635
    -       ; fun_eqs_for_me <- getInertFamEqsFor fam_tc
    
    636
    -       ; mapM_ do_one fun_eqs_for_me
    
    643
    +       ; mapM_ do_one eqs_for_me
    
    637 644
     
    
    638 645
            -- Interact with top-level instancs, emitting new Givens
    
    639 646
            ; emitNewGivens (ctEvLoc work_ev) $
    
    ... ... @@ -682,11 +689,10 @@ mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
    682 689
       = return [FDEqns { fd_qtvs = []
    
    683 690
                        , fd_eqs = map snd $ tryInteractTopFam ops fam_tc work_args work_rhs }]
    
    684 691
     
    
    685
    -mkLocalBuiltinFamEqFDs :: TyCon -> BuiltInSynFamily -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    686
    -mkLocalBuiltinFamEqFDs fam_tc ops work_args work_rhs
    
    687
    -  = do { fun_eqs_for_me <- getInertFamEqsFor fam_tc
    
    688
    -
    
    689
    -       ; let do_one :: EqCt -> [FunDepEqns]
    
    692
    +mkLocalBuiltinFamEqFDs :: [EqCt] -> TyCon -> BuiltInSynFamily
    
    693
    +                       -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    694
    +mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs
    
    695
    +  = do { let do_one :: EqCt -> [FunDepEqns]
    
    690 696
                  do_one (EqCt { eq_lhs = TyFamLHS _ inert_args, eq_rhs = inert_rhs })
    
    691 697
                    | inert_rhs `tcEqType` work_rhs = [mk_eqn inert_args]
    
    692 698
                    | otherwise                     = []
    
    ... ... @@ -697,7 +703,7 @@ mkLocalBuiltinFamEqFDs fam_tc ops work_args work_rhs
    697 703
                                        , fd_eqs = map snd $ tryInteractInertFam ops fam_tc
    
    698 704
                                                                          work_args iargs }
    
    699 705
     
    
    700
    -       ; let eqns_from_inerts = concatMap do_one fun_eqs_for_me
    
    706
    +       ; let eqns_from_inerts = concatMap do_one eqs_for_me
    
    701 707
                  eqns_from_self   = case tcSplitTyConApp_maybe work_rhs of
    
    702 708
                                       Just (tc,rhs_tys) | tc==fam_tc -> [mk_eqn rhs_tys]
    
    703 709
                                       _                              -> []
    
    ... ... @@ -717,16 +723,29 @@ mkInjectivityFDEqn inj_args qtvs lhs_args rhs_args
    717 723
         eqs = [ Pair lhs_arg rhs_arg
    
    718 724
               | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
    
    719 725
     
    
    720
    -getInertFamEqsFor :: TyCon -> TcS [EqCt]  -- Returns a mixture of Given and Wanted
    
    726
    +getInertFamEqsFor :: TyCon -> [TcType] -> Xi -> TcS [EqCt]
    
    727
    +-- Returns a mixture of Given and Wanted
    
    721 728
     -- Look in the InertSet, and return all inert equalities
    
    722 729
     --    F tys ~N# rhs
    
    723 730
     --    where F is the specified TyCon
    
    731
    +-- But filter out ones that can't possibly help, is apart from the Wanted
    
    724 732
     -- Representational equalities don't interact with type family dependencies
    
    725
    -getInertFamEqsFor fam_tc
    
    733
    +getInertFamEqsFor fam_tc work_args work_rhs
    
    726 734
       = do { IC {inert_funeqs = funeqs } <- getInertCans
    
    727 735
            ; return [ funeq_ct | equal_ct_list <- findFunEqsByTyCon funeqs fam_tc
    
    728
    -                           , funeq_ct <- equal_ct_list
    
    729
    -                           , NomEq == eq_eq_rel funeq_ct ] }
    
    736
    +                           , funeq_ct@(EqCt { eq_eq_rel = eq_rel
    
    737
    +                                            , eq_lhs = TyFamLHS _ inert_args
    
    738
    +                                            , eq_rhs = inert_rhs })
    
    739
    +                                 <- equal_ct_list
    
    740
    +                           , NomEq == eq_rel
    
    741
    +                           , not (eqnIsApart inert_args inert_rhs work_args work_rhs) ] }
    
    742
    +
    
    743
    +eqnIsApart :: [TcType] -> TcType
    
    744
    +           -> [TcType] -> TcType
    
    745
    +           -> Bool
    
    746
    +eqnIsApart lhs_tys1 rhs_ty1 lhs_tys2 rhs_ty2
    
    747
    +  = (rhs_ty1:lhs_tys1) `typeListsAreApart` (rhs_ty2:lhs_tys2)
    
    748
    +
    
    730 749
     
    
    731 750
     {- Note [Type inference for type families with injectivity]
    
    732 751
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -744,11 +763,11 @@ For /injective/, /user-defined/ type families
    744 763
       - When F is a built-in type family, we can do better;
    
    745 764
         See Note [Given/Given fundeps for built-in type families]
    
    746 765
     
    
    747
    -* (INJFAM:Wanted/Self) see `mkLocalUserFamEqFDs`
    
    766
    +* (INJFAM:Wanted/Self) see `mkLocalFamEqFDs`
    
    748 767
         work item: [W] F s1 s2 ~ F t1 t2
    
    749 768
       We can generate FunDepEqns: (s2 ~ t2)
    
    750 769
     
    
    751
    -* (INJFAM:Wanted/other) see `mkLocalUserFamEqFDs`
    
    770
    +* (INJFAM:Wanted/other) see `mkLocalFamEqFDs`
    
    752 771
         work item: [W]   F s1 s2 ~ rhs   -- Wanted
    
    753 772
         inert:     [G/W] F t2 t2 ~ rhs   -- Same `rhs`, Given or Wanted
    
    754 773
       We can generate FunDepEqns: (s2 ~ t2)