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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/FamInstEnv.hs
    ... ... @@ -611,7 +611,7 @@ injectiveBranches injectivity
    611 611
       -- See Note [Verifying injectivity annotation], case 1.
    
    612 612
       = let getInjArgs  = filterByList injectivity
    
    613 613
             in_scope    = mkInScopeSetList (tvs1 ++ tvs2)
    
    614
    -    in case tcUnifyTyForInjectivity True in_scope rhs1 rhs2 of
    
    614
    +    in case tcUnifyTysForInjectivity True in_scope [rhs1] [rhs2] of
    
    615 615
                  -- True = two-way pre-unification
    
    616 616
            Nothing -> InjectivityAccepted
    
    617 617
              -- RHS are different, so equations are injective.
    

  • compiler/GHC/Core/Unify.hs
    ... ... @@ -12,7 +12,7 @@ module GHC.Core.Unify (
    12 12
     
    
    13 13
             -- Side-effect free unification
    
    14 14
             tcUnifyTy, tcUnifyTys, tcUnifyFunDeps, tcUnifyDebugger,
    
    15
    -        tcUnifyTysFG, tcUnifyTyForInjectivity,
    
    15
    +        tcUnifyTysFG, tcUnifyTysForInjectivity,
    
    16 16
             BindTvFun, BindFamFun, BindFlag(..),
    
    17 17
             matchBindTv, alwaysBindTv, alwaysBindFam, dontCareBindFam,
    
    18 18
             UnifyResult, UnifyResultM(..), MaybeApartReason(..),
    
    ... ... @@ -381,7 +381,7 @@ Wrinkles
    381 381
     
    
    382 382
     (ATF7) There is one other, very special case of matching where we /do/ want to
    
    383 383
        bind type families in `um_fam_env`, namely in GHC.Tc.Solver.Equality, the call
    
    384
    -   to `tcUnifyTyForInjectivity False` in `improve_injective_wanted_top`.
    
    384
    +   to `tcUnifyTysForInjectivity False` in `improve_injective_wanted_top`.
    
    385 385
        Consider
    
    386 386
        of a match. Consider
    
    387 387
           type family G6 a = r | r -> a
    
    ... ... @@ -814,25 +814,25 @@ tcUnifyFunDeps qtvs tys1 tys2
    814 814
     
    
    815 815
     -- | Unify or match a type-family RHS with a type (possibly another type-family RHS)
    
    816 816
     -- Precondition: kinds are the same
    
    817
    -tcUnifyTyForInjectivity
    
    817
    +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 821
         -> InScopeSet     -- Should include the free tyvars of both Type args
    
    822
    -    -> Type -> Type   -- Types to unify
    
    822
    +    -> [Type] -> [Type]   -- Types to unify
    
    823 823
         -> Maybe Subst
    
    824 824
     -- This algorithm is an implementation of the "Algorithm U" presented in
    
    825 825
     -- the paper "Injective type families for Haskell", Figures 2 and 3.
    
    826 826
     -- The code is incorporated with the standard unifier for convenience, but
    
    827 827
     -- its operation should match the specification in the paper.
    
    828
    -tcUnifyTyForInjectivity unif in_scope t1 t2
    
    828
    +tcUnifyTysForInjectivity unif in_scope tys1 tys2
    
    829 829
       = case tc_unify_tys alwaysBindFam alwaysBindTv
    
    830 830
                            unif   -- Am I unifying?
    
    831 831
                            True   -- Do injectivity checks
    
    832 832
                            False  -- Don't check outermost kinds
    
    833 833
                            RespectMultiplicities
    
    834 834
                            rn_env emptyTvSubstEnv emptyCvSubstEnv
    
    835
    -                       [t1] [t2] of
    
    835
    +                       tys1 tys2 of
    
    836 836
           Unifiable          (tv_subst, _cv_subst) -> Just $ maybe_fix tv_subst
    
    837 837
           MaybeApart _reason (tv_subst, _cv_subst) -> Just $ maybe_fix tv_subst
    
    838 838
                      -- We want to *succeed* in questionable cases.
    

  • 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 )
    
    28
    +import GHC.Core.Unify( tcUnifyTysForInjectivity, typeListsAreApart )
    
    29 29
     import GHC.Core.Coercion.Axiom
    
    30 30
     import GHC.Core.TyCo.Subst( elemSubst )
    
    31 31
     
    
    ... ... @@ -545,14 +545,35 @@ mkTopClosedFamEqFDs :: CoAxiom Branched -> [TcType] -> Xi -> TcS [FunDepEqns]
    545 545
     mkTopClosedFamEqFDs ax work_args work_rhs
    
    546 546
       = do { let branches = fromBranches (coAxiomBranches ax)
    
    547 547
            ; traceTcS "mkTopClosed" (ppr branches $$ ppr work_args $$ ppr work_rhs)
    
    548
    -       ; case filter relevant_branch branches of
    
    549
    -           [CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys }]
    
    548
    +       ; case getRelevantBranches ax work_args work_rhs of
    
    549
    +            [CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys }]
    
    550 550
                   -> return [FDEqns { fd_qtvs = qtvs
    
    551 551
                                     , fd_eqs = zipWith Pair lhs_tys work_args }]
    
    552 552
                _  -> return [] }
    
    553
    +
    
    554
    +getRelevantBranches ax work_args work_rhs
    
    555
    +  = go [] (fromBranches (coAxiomBranches ax))
    
    553 556
       where
    
    554
    -    relevant_branch (CoAxBranch { cab_lhs = lhs_tys, cab_rhs = rhs_ty })
    
    555
    -      = eqnIsRelevant lhs_tys rhs_ty work_args work_rhs
    
    557
    +    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
    +
    
    569
    +         branch_fvs = extendVarSetList work_fvs qtvs
    
    570
    +
    
    571
    +         no_match lhs_tys [] = True
    
    572
    +         no_match lhs_tys (CoAxBranch { cab_qtvs = qtvs1, cab_lhs = lhs_tys1 })
    
    573
    +            = isNothing (tcUnifyTysForInjectivity False lhs_tys1 lhs_tys)
    
    574
    +            where
    
    575
    +              all_fvs = branch_fvs `extendVarSetList` qtvs1
    
    576
    +
    
    556 577
     
    
    557 578
     mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
    
    558 579
     -- Implements (INJFAM:Wanted/top)