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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/FamInstEnv.hs
    ... ... @@ -609,9 +609,7 @@ injectiveBranches injectivity
    609 609
                       ax1@(CoAxBranch { cab_tvs = tvs1, cab_lhs = lhs1, cab_rhs = rhs1 })
    
    610 610
                       ax2@(CoAxBranch { cab_tvs = tvs2, cab_lhs = lhs2, cab_rhs = rhs2 })
    
    611 611
       -- See Note [Verifying injectivity annotation], case 1.
    
    612
    -  = let getInjArgs  = filterByList injectivity
    
    613
    -        in_scope    = mkInScopeSetList (tvs1 ++ tvs2)
    
    614
    -    in case tcUnifyTysForInjectivity True in_scope [rhs1] [rhs2] of
    
    612
    +  = case tcUnifyTysForInjectivity True [rhs1] [rhs2] of
    
    615 613
                  -- True = two-way pre-unification
    
    616 614
            Nothing -> InjectivityAccepted
    
    617 615
              -- RHS are different, so equations are injective.
    
    ... ... @@ -633,6 +631,7 @@ injectiveBranches injectivity
    633 631
                       -- Payload of InjectivityUnified used only for check 1B2, only
    
    634 632
                       -- for closed type families
    
    635 633
             where
    
    634
    +          getInjArgs  = filterByList injectivity
    
    636 635
               lhs1Subst = Type.substTys subst (getInjArgs lhs1)
    
    637 636
               lhs2Subst = Type.substTys subst (getInjArgs lhs2)
    
    638 637
     
    

  • compiler/GHC/Core/Unify.hs
    ... ... @@ -818,14 +818,13 @@ tcUnifyTysForInjectivity
    818 818
         :: AmIUnifying  -- ^ True <=> do two-way unification;
    
    819 819
                         --   False <=> do one-way matching.
    
    820 820
                         --   See end of sec 5.2 from the paper
    
    821
    -    -> InScopeSet     -- Should include the free tyvars of both Type args
    
    822 821
         -> [Type] -> [Type]   -- Types to unify
    
    823 822
         -> Maybe Subst
    
    824 823
     -- This algorithm is an implementation of the "Algorithm U" presented in
    
    825 824
     -- the paper "Injective type families for Haskell", Figures 2 and 3.
    
    826 825
     -- The code is incorporated with the standard unifier for convenience, but
    
    827 826
     -- its operation should match the specification in the paper.
    
    828
    -tcUnifyTysForInjectivity unif in_scope tys1 tys2
    
    827
    +tcUnifyTysForInjectivity unif tys1 tys2
    
    829 828
       = case tc_unify_tys alwaysBindFam alwaysBindTv
    
    830 829
                            unif   -- Am I unifying?
    
    831 830
                            True   -- Do injectivity checks
    
    ... ... @@ -840,6 +839,10 @@ tcUnifyTysForInjectivity unif in_scope tys1 tys2
    840 839
           SurelyApart      -> Nothing
    
    841 840
       where
    
    842 841
         rn_env   = mkRnEnv2 in_scope
    
    842
    +    in_scope = mkInScopeSet (tyCoVarsOfTypes tys1 `unionVarSet` tyCoVarsOfTypes tys2)
    
    843
    +               -- The types we are unifying never contain foralls, so the
    
    844
    +               -- in-scope set is never looked at, so this free-var stuff
    
    845
    +               -- should never actually be done
    
    843 846
     
    
    844 847
         maybe_fix | unif      = niFixSubst in_scope
    
    845 848
                   | otherwise = mkTvSubst in_scope -- when matching, don't confuse
    

  • compiler/GHC/Tc/Solver/FunDeps.hs
    ... ... @@ -31,14 +31,13 @@ import GHC.Core.TyCo.Subst( elemSubst )
    31 31
     
    
    32 32
     import GHC.Builtin.Types.Literals( tryInteractTopFam, tryInteractInertFam )
    
    33 33
     
    
    34
    -import GHC.Types.Var.Env
    
    35 34
     import GHC.Types.Var.Set
    
    36 35
     
    
    37 36
     import GHC.Utils.Outputable
    
    38 37
     import GHC.Utils.Panic
    
    39 38
     
    
    40 39
     import GHC.Data.Pair
    
    41
    -import Data.Maybe( mapMaybe )
    
    40
    +import Data.Maybe( isNothing, mapMaybe )
    
    42 41
     
    
    43 42
     
    
    44 43
     {- Note [Overview of functional dependencies in type inference]
    
    ... ... @@ -546,34 +545,30 @@ mkTopClosedFamEqFDs ax work_args work_rhs
    546 545
       = do { let branches = fromBranches (coAxiomBranches ax)
    
    547 546
            ; traceTcS "mkTopClosed" (ppr branches $$ ppr work_args $$ ppr work_rhs)
    
    548 547
            ; case getRelevantBranches ax work_args work_rhs of
    
    549
    -            [CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys }]
    
    548
    +           [CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys, cab_rhs = rhs_ty }]
    
    550 549
                   -> return [FDEqns { fd_qtvs = qtvs
    
    551
    -                                , fd_eqs = zipWith Pair lhs_tys work_args }]
    
    550
    +                                , fd_eqs = zipWith Pair (rhs_ty:lhs_tys) (work_rhs:work_args) }]
    
    552 551
                _  -> return [] }
    
    553 552
     
    
    553
    +
    
    554
    +getRelevantBranches :: CoAxiom Branched -> [TcType] -> Xi -> [CoAxBranch]
    
    554 555
     getRelevantBranches ax work_args work_rhs
    
    555 556
       = go [] (fromBranches (coAxiomBranches ax))
    
    556 557
       where
    
    557 558
         work_tys = work_rhs : work_args
    
    558
    -    work_fvs = tyCoVarsOfTypes work_tys
    
    559
    -
    
    560
    -    go preceding [] = []
    
    561
    -    go preceding (CoAxBranch { cab_qtvs = qtvs, cab_lhs = lhs_tys, cab_rhs = rhs_ty } : rest)
    
    562
    -       | is_relevant = br : go (br:preceding) rest
    
    563
    -       | otherwise   =      go (br:preceding) rest
    
    564
    -       where
    
    565
    -         is_relevant = case tcUnifyTysForInjectivity True branch_fvs work_tys (rhs_ty:lhs_tys) of
    
    566
    -                          Nothing    -> False
    
    567
    -                          Just subst -> no_match (substTy subst lhs_tys) preceding
    
    568 559
     
    
    569
    -         branch_fvs = extendVarSetList work_fvs qtvs
    
    560
    +    go _ [] = []
    
    561
    +    go preceding (branch:branches)
    
    562
    +      | is_relevant branch = branch : go (branch:preceding) branches
    
    563
    +      | otherwise          =          go (branch:preceding) branches
    
    564
    +      where
    
    565
    +         is_relevant (CoAxBranch { cab_lhs = lhs_tys, cab_rhs = rhs_ty })
    
    566
    +            = case tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys) of
    
    567
    +                     Nothing    -> False
    
    568
    +                     Just subst -> all (no_match (substTys subst lhs_tys)) preceding
    
    570 569
     
    
    571
    -         no_match lhs_tys [] = True
    
    572
    -         no_match lhs_tys (CoAxBranch { cab_qtvs = qtvs1, cab_lhs = lhs_tys1 })
    
    570
    +         no_match lhs_tys (CoAxBranch { cab_lhs = lhs_tys1 })
    
    573 571
                 = isNothing (tcUnifyTysForInjectivity False lhs_tys1 lhs_tys)
    
    574
    -            where
    
    575
    -              all_fvs = branch_fvs `extendVarSetList` qtvs1
    
    576
    -
    
    577 572
     
    
    578 573
     mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    579 574
     -- Implements (INJFAM:Wanted/top)
    
    ... ... @@ -588,8 +583,7 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
    588 583
         do_one branch@(CoAxBranch { cab_tvs = branch_tvs
    
    589 584
                                   , cab_lhs = branch_lhs_tys
    
    590 585
                                   , cab_rhs = branch_rhs })
    
    591
    -      | let in_scope1 = in_scope `extendInScopeSetList` branch_tvs
    
    592
    -      , Just subst <- tcUnifyTyForInjectivity False in_scope1 branch_rhs work_rhs
    
    586
    +      | Just subst <- tcUnifyTysForInjectivity False [branch_rhs] [work_rhs]
    
    593 587
                           -- False: matching, not unifying
    
    594 588
           , let (subst', qtvs) = trim_qtvs subst branch_tvs
    
    595 589
                 branch_lhs_tys' = substTys subst' branch_lhs_tys
    
    ... ... @@ -599,8 +593,6 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
    599 593
           | otherwise
    
    600 594
           = Nothing
    
    601 595
     
    
    602
    -    in_scope = mkInScopeSet (tyCoVarsOfType work_rhs)
    
    603
    -
    
    604 596
         trim_qtvs :: Subst -> [TcTyVar] -> (Subst,[TcTyVar])
    
    605 597
         -- Tricky stuff: see (TIF1) in
    
    606 598
         -- Note [Type inference for type families with injectivity]