Simon Peyton Jones pushed to branch wip/T27828 at Glasgow Haskell Compiler / GHC
Commits:
-
545fd4fb
by ARATA Mizuki at 2026-09-22T15:03:24-04:00
-
bf17f289
by fendor at 2026-09-22T15:04:05-04:00
-
b1803ff5
by Simon Peyton Jones at 2026-09-23T22:02:23+01:00
24 changed files:
- + changelog.d/26610
- + changelog.d/T27828
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- rts/include/stg/Prim.h
- rts/prim/bitrev.c
- rts/prim/bswap.c
- + testsuite/tests/ghci/prog-mhu008/Makefile
- + testsuite/tests/ghci/prog-mhu008/a/M.hs
- + testsuite/tests/ghci/prog-mhu008/all.T
- + testsuite/tests/ghci/prog-mhu008/b/M.hs
- + testsuite/tests/ghci/prog-mhu008/prog-mhu008.script
- + testsuite/tests/ghci/prog-mhu008/prog-mhu008.stdout
- + testsuite/tests/ghci/prog-mhu008/unitA
- + testsuite/tests/ghci/prog-mhu008/unitB
- + testsuite/tests/indexed-types/should_compile/T27828.hs
- testsuite/tests/indexed-types/should_compile/all.T
- + testsuite/tests/primops/should_run/T27299.hs
- + testsuite/tests/primops/should_run/T27299.stdout
- testsuite/tests/primops/should_run/all.T
Changes:
| 1 | +section: compiler
|
|
| 2 | +synopsis: Fix instance resolution for shadowed modules
|
|
| 3 | +description:
|
|
| 4 | + Instances imported from modules with the same module name as the importing module
|
|
| 5 | + were dropped accidentally since we didn't account for the unit id of the imported module.
|
|
| 6 | +mrs: !16648
|
|
| 7 | +issues: #26610 |
| 1 | +section: compiler
|
|
| 2 | +synopsis: Fix a "No skolem info" compiler crash
|
|
| 3 | +issues: #27828
|
|
| 4 | +mrs: !16714
|
|
| 5 | + |
|
| 6 | +description: {
|
|
| 7 | + There was a bug in the implemenation of functional dependencies for type families.
|
|
| 8 | +} |
| ... | ... | @@ -197,14 +197,19 @@ Note [Storing compatibility] |
| 197 | 197 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 198 | 198 | During axiom application, we need to be aware of which branches are compatible
|
| 199 | 199 | with which others. The full explanation is in Note [Compatibility] in
|
| 200 | -GHc.Core.FamInstEnv. (The code is placed there to avoid a dependency from
|
|
| 200 | +GHC.Core.FamInstEnv. (The code is placed there to avoid a dependency from
|
|
| 201 | 201 | GHC.Core.Coercion.Axiom on the unification algorithm.) Although we could
|
| 202 | 202 | theoretically compute compatibility on the fly, this is silly, so we store it
|
| 203 | 203 | in a CoAxiom.
|
| 204 | 204 | |
| 205 | -Specifically, each branch refers to all other branches with which it is
|
|
| 206 | -incompatible. This list might well be empty, and it will always be for the
|
|
| 207 | -first branch of any axiom.
|
|
| 205 | +Specifically, the `cab_incomps :: [CoAxBranch]` field of a `CoAxBranch`
|
|
| 206 | +lists all /earlier/ branches with which it is /incompatible/. That is,
|
|
| 207 | +earlier branches where
|
|
| 208 | + 1) the patterns are not apart from the patterns of this branch, and
|
|
| 209 | + 2) if the patterns unify, the rhss are different
|
|
| 210 | + |
|
| 211 | +This list might well be empty, and it will always be for the first branch of
|
|
| 212 | +any axiom.
|
|
| 208 | 213 | |
| 209 | 214 | CoAxBranches that do not (yet) belong to a CoAxiom should have a panic thunk
|
| 210 | 215 | stored in cab_incomps. The incompatibilities are properly a property of the
|
| ... | ... | @@ -230,7 +235,9 @@ This is checked in FamInstEnv.mkCoAxBranch. |
| 230 | 235 | -- If you edit this type, you may need to update the GHC formalism
|
| 231 | 236 | -- See Note [GHC Formalism] in GHC.Core.Lint
|
| 232 | 237 | data CoAxiom br
|
| 233 | - = CoAxiom -- Type equality axiom.
|
|
| 238 | + = -- `br` is Unbranched for each of the many axioms of an open type family
|
|
| 239 | + -- Branched for the single multi-branch axiom of a closed type family
|
|
| 240 | + CoAxiom -- Type equality axiom.
|
|
| 234 | 241 | { co_ax_unique :: Unique -- Unique identifier
|
| 235 | 242 | , co_ax_name :: Name -- Name for pretty-printing
|
| 236 | 243 | , co_ax_role :: Role -- Role of the axiom's equality
|
| ... | ... | @@ -19,7 +19,7 @@ module GHC.Core.FamInstEnv ( |
| 19 | 19 | FamInstMatch(..),
|
| 20 | 20 | lookupFamInstEnv, lookupFamInstEnvConflicts, lookupFamInstEnvByTyCon,
|
| 21 | 21 | |
| 22 | - isDominatedBy, apartnessCheck, compatibleBranches,
|
|
| 22 | + isDominatedBy, apartnessCheck, noEarlierMatchCheck, compatibleBranches,
|
|
| 23 | 23 | |
| 24 | 24 | -- Injectivity
|
| 25 | 25 | InjectivityCheckResult(..),
|
| ... | ... | @@ -488,9 +488,11 @@ in GHC.Core.Unify.) |
| 488 | 488 | Note [Compatibility]
|
| 489 | 489 | ~~~~~~~~~~~~~~~~~~~~
|
| 490 | 490 | Two patterns are /compatible/ if either of the following conditions hold:
|
| 491 | -1) The patterns are apart.
|
|
| 492 | -2) The patterns unify with a substitution S, and their right hand sides
|
|
| 493 | -equal under that substitution.
|
|
| 491 | + |
|
| 492 | + 1) The patterns are apart.
|
|
| 493 | + |
|
| 494 | + 2) The patterns unify with a substitution S, and their right hand sides
|
|
| 495 | + are equal under that substitution.
|
|
| 494 | 496 | |
| 495 | 497 | For open type families, only compatible instances are allowed. For closed
|
| 496 | 498 | type families, the story is slightly more complicated. Consider the following:
|
| ... | ... | @@ -603,8 +605,7 @@ injectiveBranches injectivity |
| 603 | 605 | ax1@(CoAxBranch { cab_lhs = lhs1, cab_rhs = rhs1 })
|
| 604 | 606 | ax2@(CoAxBranch { cab_lhs = lhs2, cab_rhs = rhs2 })
|
| 605 | 607 | -- See Note [Verifying injectivity annotation], case 1.
|
| 606 | - = case tcUnifyTysForInjectivity True [rhs1] [rhs2] of
|
|
| 607 | - -- True = two-way pre-unification
|
|
| 608 | + = case tcUnifyTysForInjectivity Unifying [rhs1] [rhs2] of
|
|
| 608 | 609 | Nothing -> InjectivityAccepted
|
| 609 | 610 | -- RHS are different, so equations are injective.
|
| 610 | 611 | -- This is case 1A from Note [Verifying injectivity annotation]
|
| ... | ... | @@ -1258,6 +1259,17 @@ apartnessCheck target (CoAxBranch { cab_incomps = incomps }) |
| 1258 | 1259 | isSurelyApart SurelyApart = True
|
| 1259 | 1260 | isSurelyApart _ = False
|
| 1260 | 1261 | |
| 1262 | +-- | Check whether an earlier branch matches these target types
|
|
| 1263 | +noEarlierMatchCheck
|
|
| 1264 | + :: [Type]
|
|
| 1265 | + -> CoAxBranch -- ^ The candidate equation we wish to use
|
|
| 1266 | + -> Bool -- ^ True <=> equation can fire
|
|
| 1267 | +noEarlierMatchCheck target (CoAxBranch { cab_incomps = incomps })
|
|
| 1268 | + = not (any matches incomps)
|
|
| 1269 | + where
|
|
| 1270 | + matches earlier_branch
|
|
| 1271 | + = isJust (tcMatchTys (coAxBranchLHS earlier_branch) target)
|
|
| 1272 | + |
|
| 1261 | 1273 | {-
|
| 1262 | 1274 | ************************************************************************
|
| 1263 | 1275 | * *
|
| ... | ... | @@ -9,6 +9,7 @@ module GHC.Core.Unify ( |
| 9 | 9 | tcMatchTyX_BM, ruleMatchTyKiX,
|
| 10 | 10 | |
| 11 | 11 | -- Side-effect free unification
|
| 12 | + AmIUnifying(..),
|
|
| 12 | 13 | tcUnifyTy, tcUnifyTys, tcUnifyFunDeps, tcUnifyDebugger,
|
| 13 | 14 | tcUnifyTysFG, tcUnifyTysForInjectivity,
|
| 14 | 15 | BindTvFun, BindFamFun, BindFlag(..),
|
| ... | ... | @@ -597,14 +598,14 @@ tcMatchTyX_BM :: HasDebugCallStack |
| 597 | 598 | => BindTvFun -> Subst
|
| 598 | 599 | -> Type -> Type -> Maybe Subst
|
| 599 | 600 | tcMatchTyX_BM bind_tv subst ty1 ty2
|
| 600 | - = tc_match_tys_x bind_tv False subst [ty1] [ty2]
|
|
| 601 | + = tc_match_tys_x bind_tv IgnoreOuterKinds subst [ty1] [ty2]
|
|
| 601 | 602 | |
| 602 | 603 | -- | Like 'tcMatchTy', but allows the kinds of the types to differ,
|
| 603 | 604 | -- and thus matches them as well.
|
| 604 | 605 | -- See also Note [tcMatchTy vs tcMatchTyKi]
|
| 605 | 606 | tcMatchTyKi :: HasDebugCallStack => Type -> Type -> Maybe Subst
|
| 606 | 607 | tcMatchTyKi ty1 ty2
|
| 607 | - = tc_match_tys alwaysBindTv True [ty1] [ty2]
|
|
| 608 | + = tc_match_tys alwaysBindTv CheckOuterKinds [ty1] [ty2]
|
|
| 608 | 609 | |
| 609 | 610 | -- | This is similar to 'tcMatchTy', but extends a substitution
|
| 610 | 611 | -- See also Note [tcMatchTy vs tcMatchTyKi]
|
| ... | ... | @@ -614,7 +615,7 @@ tcMatchTyX :: HasDebugCallStack |
| 614 | 615 | -> Type -- ^ Target
|
| 615 | 616 | -> Maybe Subst
|
| 616 | 617 | tcMatchTyX subst ty1 ty2
|
| 617 | - = tc_match_tys_x alwaysBindTv False subst [ty1] [ty2]
|
|
| 618 | + = tc_match_tys_x alwaysBindTv IgnoreOuterKinds subst [ty1] [ty2]
|
|
| 618 | 619 | |
| 619 | 620 | -- | Like 'tcMatchTy' but over a list of types.
|
| 620 | 621 | -- See also Note [tcMatchTy vs tcMatchTyKi]
|
| ... | ... | @@ -625,7 +626,7 @@ tcMatchTys :: HasDebugCallStack |
| 625 | 626 | -- variables could be free in the target
|
| 626 | 627 | -- See (CU6) in Note [The Core unifier]
|
| 627 | 628 | tcMatchTys tys1 tys2
|
| 628 | - = tc_match_tys alwaysBindTv False tys1 tys2
|
|
| 629 | + = tc_match_tys alwaysBindTv IgnoreOuterKinds tys1 tys2
|
|
| 629 | 630 | |
| 630 | 631 | -- | Like 'tcMatchTyKi' but over a list of types.
|
| 631 | 632 | -- See also Note [tcMatchTy vs tcMatchTyKi]
|
| ... | ... | @@ -635,7 +636,7 @@ tcMatchTyKis :: HasDebugCallStack |
| 635 | 636 | -> Maybe Subst -- ^ One-shot substitution
|
| 636 | 637 | -- See (CU6) in Note [The Core unifier]
|
| 637 | 638 | tcMatchTyKis tys1 tys2
|
| 638 | - = tc_match_tys alwaysBindTv True tys1 tys2
|
|
| 639 | + = tc_match_tys alwaysBindTv CheckOuterKinds tys1 tys2
|
|
| 639 | 640 | |
| 640 | 641 | -- | Like 'tcMatchTys', but extending a substitution
|
| 641 | 642 | -- See also Note [tcMatchTy vs tcMatchTyKi]
|
| ... | ... | @@ -645,7 +646,7 @@ tcMatchTysX :: HasDebugCallStack |
| 645 | 646 | -> [Type] -- ^ Target
|
| 646 | 647 | -> Maybe Subst -- ^ One-shot substitution
|
| 647 | 648 | tcMatchTysX subst tys1 tys2
|
| 648 | - = tc_match_tys_x alwaysBindTv False subst tys1 tys2
|
|
| 649 | + = tc_match_tys_x alwaysBindTv IgnoreOuterKinds subst tys1 tys2
|
|
| 649 | 650 | |
| 650 | 651 | -- | Like 'tcMatchTyKis', but extending a substitution
|
| 651 | 652 | -- See also Note [tcMatchTy vs tcMatchTyKi]
|
| ... | ... | @@ -655,12 +656,12 @@ tcMatchTyKisX :: HasDebugCallStack |
| 655 | 656 | -> [Type] -- ^ Target
|
| 656 | 657 | -> Maybe Subst -- ^ One-shot substitution
|
| 657 | 658 | tcMatchTyKisX subst tys1 tys2
|
| 658 | - = tc_match_tys_x alwaysBindTv True subst tys1 tys2
|
|
| 659 | + = tc_match_tys_x alwaysBindTv CheckOuterKinds subst tys1 tys2
|
|
| 659 | 660 | |
| 660 | 661 | -- | Same as tc_match_tys_x, but starts with an empty substitution
|
| 661 | 662 | tc_match_tys :: HasDebugCallStack
|
| 662 | 663 | => BindTvFun
|
| 663 | - -> Bool -- ^ match kinds?
|
|
| 664 | + -> OuterKindsFlag -- ^ Match kinds?
|
|
| 664 | 665 | -> [Type]
|
| 665 | 666 | -> [Type]
|
| 666 | 667 | -> Maybe Subst
|
| ... | ... | @@ -672,7 +673,7 @@ tc_match_tys bind_me match_kis tys1 tys2 |
| 672 | 673 | -- | Worker for 'tcMatchTysX' and 'tcMatchTyKisX'
|
| 673 | 674 | tc_match_tys_x :: HasDebugCallStack
|
| 674 | 675 | => BindTvFun
|
| 675 | - -> Bool -- ^ match kinds?
|
|
| 676 | + -> OuterKindsFlag -- ^ Match kinds?
|
|
| 676 | 677 | -> Subst
|
| 677 | 678 | -> [Type]
|
| 678 | 679 | -> [Type]
|
| ... | ... | @@ -680,8 +681,8 @@ tc_match_tys_x :: HasDebugCallStack |
| 680 | 681 | tc_match_tys_x bind_tv match_kis (Subst in_scope id_env tv_env cv_env) tys1 tys2
|
| 681 | 682 | = case tc_unify_tys neverBindFam -- (ATF7) in Note [Apartness and type families]
|
| 682 | 683 | bind_tv
|
| 683 | - False -- Matching, not unifying
|
|
| 684 | - False -- Not an injectivity check
|
|
| 684 | + Matching -- Matching, not unifying
|
|
| 685 | + False -- Not an injectivity check
|
|
| 685 | 686 | match_kis
|
| 686 | 687 | RespectMultiplicities
|
| 687 | 688 | (mkRnEnv2 in_scope) tv_env cv_env tys1 tys2 of
|
| ... | ... | @@ -706,9 +707,9 @@ ruleMatchTyKiX tmpl_tvs rn_env tenv tmpl target |
| 706 | 707 | -- But even if it did, (ATF8) in Note [Apartness and type families]
|
| 707 | 708 | -- says it doesn't matter becuase here we only care about Unifiable.
|
| 708 | 709 | -- So neverBindFam is efficient, and sufficient.
|
| 709 | - False -- Matching, not unifying
|
|
| 710 | + Matching -- Matching, not unifying
|
|
| 710 | 711 | False -- No doing an injectivity check
|
| 711 | - True -- Match the kinds
|
|
| 712 | + CheckOuterKinds -- Match the kinds
|
|
| 712 | 713 | IgnoreMultiplicities
|
| 713 | 714 | -- See Note [Rewrite rules ignore multiplicities in FunTy]
|
| 714 | 715 | rn_env tenv emptyCvSubstEnv [tmpl] [target] of
|
| ... | ... | @@ -784,7 +785,7 @@ tcUnifyTy t1 t2 = tcUnifyTys alwaysBindTv [t1] [t2] |
| 784 | 785 | tcUnifyDebugger :: Type -> Type -> Maybe Subst
|
| 785 | 786 | tcUnifyDebugger t1 t2
|
| 786 | 787 | = case tc_unify_tys_fg
|
| 787 | - True -- Unify kinds
|
|
| 788 | + CheckOuterKinds -- Unify kinds
|
|
| 788 | 789 | neverBindFam -- Does not affect Unifiable, so pick max efficient
|
| 789 | 790 | -- See (ATF8) in Note [Apartness and type families]
|
| 790 | 791 | alwaysBindTv
|
| ... | ... | @@ -798,7 +799,7 @@ tcUnifyFunDeps :: TyCoVarSet |
| 798 | 799 | -> Maybe Subst
|
| 799 | 800 | tcUnifyFunDeps qtvs tys1 tys2
|
| 800 | 801 | = case tc_unify_tys_fg
|
| 801 | - True -- Unify kinds
|
|
| 802 | + CheckOuterKinds -- Unify kinds
|
|
| 802 | 803 | dontCareBindFam -- Class-instance heads never mention type families
|
| 803 | 804 | (matchBindTv qtvs)
|
| 804 | 805 | tys1 tys2 of
|
| ... | ... | @@ -821,7 +822,7 @@ tcUnifyTysForInjectivity unif tys1 tys2 |
| 821 | 822 | = case tc_unify_tys alwaysBindFam alwaysBindTv
|
| 822 | 823 | unif -- Am I unifying?
|
| 823 | 824 | True -- Do injectivity checks
|
| 824 | - False -- Don't check outermost kinds
|
|
| 825 | + IgnoreOuterKinds -- Don't check outermost kinds
|
|
| 825 | 826 | RespectMultiplicities
|
| 826 | 827 | rn_env emptyTvSubstEnv emptyCvSubstEnv
|
| 827 | 828 | tys1 tys2 of
|
| ... | ... | @@ -838,8 +839,9 @@ tcUnifyTysForInjectivity unif tys1 tys2 |
| 838 | 839 | -- should never actually be done
|
| 839 | 840 | |
| 840 | 841 | maybe_fix tv_subst
|
| 841 | - | unif = niFixSubst in_scope tv_subst
|
|
| 842 | - | otherwise = mkTvSubst in_scope tv_subst
|
|
| 842 | + = case unif of
|
|
| 843 | + Unifying -> niFixSubst in_scope tv_subst
|
|
| 844 | + Matching -> mkTvSubst in_scope tv_subst
|
|
| 843 | 845 | -- When matching, don't confuse domain with range; no fixpoint!
|
| 844 | 846 | |
| 845 | 847 | -----------------
|
| ... | ... | @@ -866,15 +868,15 @@ tcUnifyTysFG :: BindFamFun -> BindTvFun |
| 866 | 868 | -> [Type] -> [Type]
|
| 867 | 869 | -> UnifyResult
|
| 868 | 870 | tcUnifyTysFG bind_fam bind_tv tys1 tys2
|
| 869 | - = tc_unify_tys_fg False bind_fam bind_tv tys1 tys2
|
|
| 871 | + = tc_unify_tys_fg IgnoreOuterKinds bind_fam bind_tv tys1 tys2
|
|
| 870 | 872 | |
| 871 | -tc_unify_tys_fg :: Bool
|
|
| 873 | +tc_unify_tys_fg :: OuterKindsFlag
|
|
| 872 | 874 | -> BindFamFun -> BindTvFun
|
| 873 | 875 | -> [Type] -> [Type]
|
| 874 | 876 | -> UnifyResult
|
| 875 | 877 | tc_unify_tys_fg match_kis bind_fam bind_tv tys1 tys2
|
| 876 | 878 | = do { (tv_env, _) <- tc_unify_tys bind_fam bind_tv
|
| 877 | - True -- Unifying
|
|
| 879 | + Unifying
|
|
| 878 | 880 | False -- Not doing an injectivity check
|
| 879 | 881 | match_kis -- Match outer kinds
|
| 880 | 882 | RespectMultiplicities rn_env
|
| ... | ... | @@ -888,10 +890,10 @@ tc_unify_tys_fg match_kis bind_fam bind_tv tys1 tys2 |
| 888 | 890 | -- | This function is actually the one to call the unifier -- a little
|
| 889 | 891 | -- too general for outside clients, though.
|
| 890 | 892 | tc_unify_tys :: BindFamFun -> BindTvFun
|
| 891 | - -> AmIUnifying -- ^ True <=> unify; False <=> match
|
|
| 892 | - -> Bool -- ^ True <=> doing an injectivity check
|
|
| 893 | - -> Bool -- ^ True <=> treat the kinds as well
|
|
| 894 | - -> MultiplicityFlag -- ^ see Note [Rewrite rules ignore multiplicities in FunTy] in GHC.Core.Unify
|
|
| 893 | + -> AmIUnifying -- ^ Unifying or matching
|
|
| 894 | + -> Bool -- ^ True <=> doing an injectivity check
|
|
| 895 | + -> OuterKindsFlag -- ^ Check outer kinds or not
|
|
| 896 | + -> MultiplicityFlag -- ^ see Note [Rewrite rules ignore multiplicities in FunTy] in GHC.Core.Unify
|
|
| 895 | 897 | -> RnEnv2
|
| 896 | 898 | -> TvSubstEnv -- ^ substitution to extend
|
| 897 | 899 | -> CvSubstEnv
|
| ... | ... | @@ -910,8 +912,9 @@ tc_unify_tys :: BindFamFun -> BindTvFun |
| 910 | 912 | -- See also Note [tcMatchTy vs tcMatchTyKi].
|
| 911 | 913 | tc_unify_tys bind_fam bind_tv unif inj_check match_kis match_mults rn_env tv_env cv_env tys1 tys2
|
| 912 | 914 | = initUM tv_env cv_env $
|
| 913 | - do { when match_kis $
|
|
| 914 | - unify_tys env kis1 kis2
|
|
| 915 | + do { case match_kis of
|
|
| 916 | + CheckOuterKinds -> unify_tys env kis1 kis2
|
|
| 917 | + IgnoreOuterKinds -> return ()
|
|
| 915 | 918 | ; unify_tys env tys1 tys2 }
|
| 916 | 919 | where
|
| 917 | 920 | env = UMEnv { um_bind_tv_fun = bind_tv
|
| ... | ... | @@ -926,6 +929,11 @@ tc_unify_tys bind_fam bind_tv unif inj_check match_kis match_mults rn_env tv_env |
| 926 | 929 | kis2 = map typeKind tys2
|
| 927 | 930 | |
| 928 | 931 | |
| 932 | +data OuterKindsFlag
|
|
| 933 | + = CheckOuterKinds -- Unify or match the /kind/ of the two types
|
|
| 934 | + | IgnoreOuterKinds -- Just unify of match the types, ignoring kinds
|
|
| 935 | + -- (typically, we already know they are equal)
|
|
| 936 | + |
|
| 929 | 937 | {- *********************************************************************
|
| 930 | 938 | * *
|
| 931 | 939 | UnifyResult, MaybeApart etc
|
| ... | ... | @@ -1583,8 +1591,7 @@ c.f. Note [Comparing type synonyms] in GHC.Core.TyCo.Compare |
| 1583 | 1591 | |
| 1584 | 1592 | -------------- unify_ty: the main workhorse -----------
|
| 1585 | 1593 | |
| 1586 | -type AmIUnifying = Bool -- True <=> Unifying
|
|
| 1587 | - -- False <=> Matching
|
|
| 1594 | +data AmIUnifying = Matching | Unifying
|
|
| 1588 | 1595 | |
| 1589 | 1596 | type InType = Type -- Before applying the RnEnv2
|
| 1590 | 1597 | type OutCoercion = Coercion -- After applying the RnEnv2
|
| ... | ... | @@ -1618,7 +1625,7 @@ unify_ty env (CastTy ty1 co1) ty2 kco |
| 1618 | 1625 | -- See (KCU1) in Note [Kind coercions in Unify]
|
| 1619 | 1626 | = maybeApart MARCast -- See (KCU2)
|
| 1620 | 1627 | |
| 1621 | - | um_unif env
|
|
| 1628 | + | Unifying <- um_unif env
|
|
| 1622 | 1629 | = unify_ty env ty1 ty2 (co1 `mkTransCo` kco)
|
| 1623 | 1630 | |
| 1624 | 1631 | | otherwise -- We are matching, not unifying
|
| ... | ... | @@ -1661,7 +1668,7 @@ unify_ty env (CoercionTy co1) (CoercionTy co2) kco |
| 1661 | 1668 | = do { c_subst <- getCvSubstEnv
|
| 1662 | 1669 | ; case co1 of
|
| 1663 | 1670 | CoVarCo cv
|
| 1664 | - | not (um_unif env)
|
|
| 1671 | + | Matching <- um_unif env
|
|
| 1665 | 1672 | , not (cv `elemVarEnv` c_subst) -- Not forall-bound
|
| 1666 | 1673 | , let (_mult_co, co_l, co_r) = decomposeFunCo kco
|
| 1667 | 1674 | -- Because the coercion is used in a type, it should be safe to
|
| ... | ... | @@ -1682,7 +1689,7 @@ unify_ty env (TyVarTy tv1) ty2 kco |
| 1682 | 1689 | = uVarOrFam env (TyVarLHS tv1) ty2 kco
|
| 1683 | 1690 | |
| 1684 | 1691 | unify_ty env ty1 (TyVarTy tv2) kco
|
| 1685 | - | um_unif env -- If unifying, can swap args; but not when matching
|
|
| 1692 | + | Unifying <- um_unif env -- If unifying, can swap args; but not when matching
|
|
| 1686 | 1693 | = uVarOrFam (umSwapRn env) (TyVarLHS tv2) ty1 (mkSymCo kco)
|
| 1687 | 1694 | |
| 1688 | 1695 | -- Deal with TyConApps
|
| ... | ... | @@ -1692,7 +1699,7 @@ unify_ty env ty1 ty2 kco |
| 1692 | 1699 | | Just (tc,tys) <- mb_sat_fam_app1
|
| 1693 | 1700 | = uVarOrFam env (TyFamLHS tc tys) ty2 kco
|
| 1694 | 1701 | |
| 1695 | - | um_unif env
|
|
| 1702 | + | Unifying <- um_unif env
|
|
| 1696 | 1703 | , Just (tc,tys) <- mb_sat_fam_app2
|
| 1697 | 1704 | = uVarOrFam (umSwapRn env) (TyFamLHS tc tys) ty1 (mkSymCo kco)
|
| 1698 | 1705 | |
| ... | ... | @@ -1820,7 +1827,7 @@ uVarOrFam env ty1 ty2 kco |
| 1820 | 1827 | go swapped substs lhs@(TyVarLHS tv1) ty2 kco
|
| 1821 | 1828 | | Just ty1' <- lookupVarEnv (um_tv_env substs) tv1'
|
| 1822 | 1829 | = -- We already have a substitution for tv1
|
| 1823 | - if | um_unif env -> unify_ty env ty1' ty2 kco
|
|
| 1830 | + if | Unifying <- um_unif env -> unify_ty env ty1' ty2 kco
|
|
| 1824 | 1831 | | (ty1' `mkCastTy` kco) `tcEqType` ty2 -> return ()
|
| 1825 | 1832 | | otherwise -> surelyApart
|
| 1826 | 1833 | -- Unifying: recurse into unify_ty
|
| ... | ... | @@ -1842,9 +1849,9 @@ uVarOrFam env ty1 ty2 kco |
| 1842 | 1849 | | TyVarTy tv2 <- ty2
|
| 1843 | 1850 | , let tv2' = umRnOccR env tv2
|
| 1844 | 1851 | , tv1' == tv2'
|
| 1845 | - = if | um_unif env -> return ()
|
|
| 1846 | - | tv1_is_bindable -> extendTvEnv tv1' ty2
|
|
| 1847 | - | otherwise -> return ()
|
|
| 1852 | + = if | Unifying <- um_unif env -> return ()
|
|
| 1853 | + | tv1_is_bindable -> extendTvEnv tv1' ty2
|
|
| 1854 | + | otherwise -> return ()
|
|
| 1848 | 1855 | |
| 1849 | 1856 | | tv1_is_bindable
|
| 1850 | 1857 | , not (mentionsForAllBoundTyVarsR env ty2_fvs)
|
| ... | ... | @@ -1858,9 +1865,9 @@ uVarOrFam env ty1 ty2 kco |
| 1858 | 1865 | -- e.g. a ~ F p q with `a` not bindable: we might succeed with go_fam
|
| 1859 | 1866 | -- e.g. a ~ beta with `a` not bindable: we might be able to bind `beta`
|
| 1860 | 1867 | -- e.g. beta ~ F beta Int occurs check; but MaybeApart after swapping
|
| 1861 | - | um_unif env
|
|
| 1868 | + | Unifying <- um_unif env
|
|
| 1862 | 1869 | , NotSwapped <- swapped -- If we have swapped already, don't do so again
|
| 1863 | - , Just lhs2 <- canEqLHS_maybe ty2
|
|
| 1870 | + , Just lhs2 <- canEqLHS_maybe ty2
|
|
| 1864 | 1871 | = go IsSwapped substs lhs2 (mkTyVarTy tv1) (mkSymCo kco)
|
| 1865 | 1872 | |
| 1866 | 1873 | | occurs_check = maybeApart MARInfinite -- Occurs check
|
| ... | ... | @@ -1879,7 +1886,9 @@ uVarOrFam env ty1 ty2 kco |
| 1879 | 1886 | | otherwise
|
| 1880 | 1887 | = False
|
| 1881 | 1888 | |
| 1882 | - occurs_check = um_unif env && uOccursCheck substs foralld_tvs lhs rhs
|
|
| 1889 | + occurs_check = case um_unif env of
|
|
| 1890 | + Unifying -> uOccursCheck substs foralld_tvs lhs rhs
|
|
| 1891 | + Matching -> False
|
|
| 1883 | 1892 | -- Occurs check, only when unifying
|
| 1884 | 1893 | -- see Note [Infinitary substitutions]
|
| 1885 | 1894 | -- Make sure you include `kco` in rhs #14846
|
| ... | ... | @@ -1893,7 +1902,7 @@ uVarOrFam env ty1 ty2 kco |
| 1893 | 1902 | -- Hence the RnEnv2 is empty
|
| 1894 | 1903 | | not under_forall
|
| 1895 | 1904 | , Just ty1' <- lookupFamEnv (um_fam_env substs) tc1 tys1
|
| 1896 | - = if | um_unif env -> unify_ty env ty1' ty2 kco
|
|
| 1905 | + = if | Unifying <- um_unif env -> unify_ty env ty1' ty2 kco
|
|
| 1897 | 1906 | -- Below here we are matching
|
| 1898 | 1907 | -- The return () case deals with:
|
| 1899 | 1908 | -- Template: (F a)..(F a)
|
| ... | ... | @@ -1930,9 +1939,9 @@ uVarOrFam env ty1 ty2 kco |
| 1930 | 1939 | -- NB: a type family can appear on the template when matching
|
| 1931 | 1940 | -- see (ATF6) in Note [Apartness and type families]
|
| 1932 | 1941 | -- (Only worth doing this if we are not under a forall.)
|
| 1933 | - | um_unif env
|
|
| 1942 | + | Unifying <- um_unif env
|
|
| 1934 | 1943 | , NotSwapped <- swapped
|
| 1935 | - , Just lhs2 <- canEqLHS_maybe ty2
|
|
| 1944 | + , Just lhs2 <- canEqLHS_maybe ty2
|
|
| 1936 | 1945 | = go IsSwapped substs lhs2 (mkTyConApp tc1 tys1) (mkSymCo kco)
|
| 1937 | 1946 | |
| 1938 | 1947 | | otherwise -- See (ATF5) in Note [Apartness and type families]
|
| ... | ... | @@ -1962,9 +1971,9 @@ uVarOrFam env ty1 ty2 kco |
| 1962 | 1971 | (inj_tys2, noninj_tys2) = partitionByList inj tys2
|
| 1963 | 1972 | |
| 1964 | 1973 | bind_fam_if_poss
|
| 1965 | - | not (um_unif env) -- Not when matching (ATF11-1)
|
|
| 1974 | + | Matching <- um_unif env -- Not when matching (ATF11-1)
|
|
| 1966 | 1975 | = return ()
|
| 1967 | - | under_forall -- Not under a forall (ATF3)
|
|
| 1976 | + | under_forall -- Not under a forall (ATF3)
|
|
| 1968 | 1977 | = return ()
|
| 1969 | 1978 | | BindMe <- um_bind_fam_fun env tc tys1 rhs1
|
| 1970 | 1979 | = unless (uOccursCheck substs emptyVarSet (TyFamLHS tc tys1) rhs1) $
|
| ... | ... | @@ -263,13 +263,13 @@ hugCompleteSigsBelow hsc uid mn = foldr (++) [] <$> |
| 263 | 263 | -- | Find instances visible from the given set of imports
|
| 264 | 264 | hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst])
|
| 265 | 265 | hugInstancesBelow hsc_env uid mnwib = do
|
| 266 | - let mn = gwib_mod mnwib
|
|
| 266 | + let mn = mkModule uid (gwib_mod mnwib)
|
|
| 267 | 267 | (insts, famInsts) <-
|
| 268 | 268 | unzip . concat <$>
|
| 269 | 269 | hugSomeThingsBelowUs (\mod_info ->
|
| 270 | 270 | let details = hm_details mod_info
|
| 271 | 271 | -- Don't include instances for the current module
|
| 272 | - in if moduleName (mi_module (hm_iface mod_info)) == mn
|
|
| 272 | + in if fmap toUnitId (mi_module (hm_iface mod_info)) == mn
|
|
| 273 | 273 | then []
|
| 274 | 274 | else [(md_insts details, md_fam_insts details)])
|
| 275 | 275 | True -- Include -hi-boot
|
| ... | ... | @@ -136,10 +136,10 @@ data FunDepEqns -- Plural becuase fd_eqs has multiple equations |
| 136 | 136 | -- to fresh unification vars,
|
| 137 | 137 | -- See (IMP2) in Note [Improving against instances]
|
| 138 | 138 | |
| 139 | - , fd_eqs :: [TypeEqn] -- Make these pairs of types equal
|
|
| 140 | - -- Invariant: In each (Pair ty1 ty2), the fd_qtvs may be
|
|
| 141 | - -- free in ty1 but not in ty2. See Wrinkle (1) of
|
|
| 142 | - -- Note [Improving against instances]
|
|
| 139 | + , fd_eqs :: [TypeEqn] -- Make these pairs of types equal
|
|
| 140 | + -- Invariant: In each (Pair ty1 ty2), the fd_qtvs may be
|
|
| 141 | + -- free in ty1 but not in ty2. See Wrinkle (1) of
|
|
| 142 | + -- Note [Improving against instances]
|
|
| 143 | 143 | }
|
| 144 | 144 | |
| 145 | 145 | instance Outputable FunDepEqns where
|
| ... | ... | @@ -26,12 +26,14 @@ import GHC.Core.Coercion |
| 26 | 26 | import GHC.Core.TyCo.Rep( Type(..) )
|
| 27 | 27 | import GHC.Core.Predicate( EqRel(..) )
|
| 28 | 28 | import GHC.Core.TyCon
|
| 29 | -import GHC.Core.Unify( tcUnifyTysForInjectivity, typeListsAreApart )
|
|
| 29 | +import GHC.Core.Unify( AmIUnifying(..)
|
|
| 30 | + , tcUnifyTysForInjectivity, typeListsAreApart )
|
|
| 30 | 31 | import GHC.Core.Coercion.Axiom
|
| 31 | 32 | import GHC.Core.TyCo.Subst( elemSubst )
|
| 32 | 33 | |
| 33 | 34 | import GHC.Builtin.WiredIn.TypeLits( tryInteractTopFam, tryInteractInertFam )
|
| 34 | 35 | |
| 36 | +import GHC.Types.Var( TyVar, tyVarKind, setTyVarKind )
|
|
| 35 | 37 | import GHC.Types.Var.Set
|
| 36 | 38 | |
| 37 | 39 | import GHC.Utils.Outputable
|
| ... | ... | @@ -39,7 +41,7 @@ import GHC.Utils.Panic |
| 39 | 41 | |
| 40 | 42 | import Control.Monad( unless )
|
| 41 | 43 | import GHC.Data.Pair
|
| 42 | -import Data.Maybe( isNothing, isJust, mapMaybe )
|
|
| 44 | +import Data.Maybe( isJust, mapMaybe )
|
|
| 43 | 45 | |
| 44 | 46 | |
| 45 | 47 | {- Note [Overview of functional dependencies in type inference]
|
| ... | ... | @@ -109,7 +111,6 @@ Wrinkles |
| 109 | 111 | from fundeps, but that would require new evidence forms, and an extension to
|
| 110 | 112 | FC, so we don't do that right now (Dec 14).
|
| 111 | 113 | |
| 112 | - |
|
| 113 | 114 | Note [FunDep and implicit parameter reactions]
|
| 114 | 115 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 115 | 116 | Currently, our story of interacting two dictionaries (or a dictionary
|
| ... | ... | @@ -573,6 +574,7 @@ tryEqFunDeps work_item@(EqCt { eq_lhs = work_lhs |
| 573 | 574 | |
| 574 | 575 | |
| 575 | 576 | tryFamEqFunDeps :: TcSMode -> [EqCt] -> TyCon -> [TcType] -> EqCt -> SolverStage ()
|
| 577 | +-- See Note [Type inference for type families with injectivity]
|
|
| 576 | 578 | tryFamEqFunDeps mode eqs_for_me fam_tc work_args
|
| 577 | 579 | work_item@(EqCt { eq_ev = ev, eq_rhs = work_rhs })
|
| 578 | 580 | | Just ops <- builtInClosedTyFamTyCon_maybe fam_tc
|
| ... | ... | @@ -583,6 +585,7 @@ tryFamEqFunDeps mode eqs_for_me fam_tc work_args |
| 583 | 585 | ; tryFDEqns False fam_tc work_args work_item eqns
|
| 584 | 586 | |
| 585 | 587 | ; unless (hasRelevantGiven eqs_for_me work_args work_item) $
|
| 588 | + -- hasRelevantGiven: See (CF1) in Note [Exploiting closed type families]
|
|
| 586 | 589 | do { eqns <- mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
|
| 587 | 590 | ; tryFDEqns True fam_tc work_args work_item eqns } }
|
| 588 | 591 | |
| ... | ... | @@ -599,8 +602,11 @@ tryFamEqFunDeps mode eqs_for_me fam_tc work_args |
| 599 | 602 | NotInjective -> nopStage ()
|
| 600 | 603 | Injective inj -> do { eqns <- mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
|
| 601 | 604 | ; tryFDEqns False fam_tc work_args work_item eqns }
|
| 605 | + -- NB: tryFDEqns bales out on an insoluble fundep
|
|
| 606 | + -- See (CF4) in Note [Exploiting closed type families]
|
|
| 602 | 607 | |
| 603 | 608 | ; unless (hasRelevantGiven eqs_for_me work_args work_item) $
|
| 609 | + -- hasRelevantGiven: See (CF1) in Note [Exploiting closed type families]
|
|
| 604 | 610 | do { eqns <- mkTopFamEqFDs fam_tc work_args work_item
|
| 605 | 611 | ; tryFDEqns True fam_tc work_args work_item eqns } }
|
| 606 | 612 | |
| ... | ... | @@ -638,10 +644,11 @@ tryFDEqns is_top fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) f |
| 638 | 644 | -- User-defined type families
|
| 639 | 645 | -----------------------------------------
|
| 640 | 646 | mkTopClosedFamEqFDs :: CoAxiom Branched -> [TcType] -> EqCt -> SolverStage [FunDepEqns]
|
| 647 | +-- Implements (INJFAM:Wanted/top-closed)
|
|
| 648 | +-- See Note [Exploiting closed type families]
|
|
| 641 | 649 | -- Look at the top-level axioms; we effectively infer injectivity,
|
| 642 | --- so we don't need tyConInjectivtyInfo. This works fine for closed
|
|
| 650 | +-- so we don't need tyConInjectivityInfo. This works fine for closed
|
|
| 643 | 651 | -- type families without injectivity info
|
| 644 | --- See Note [Exploiting closed type families]
|
|
| 645 | 652 | mkTopClosedFamEqFDs ax work_args (EqCt { eq_ev = ev, eq_rhs = work_rhs })
|
| 646 | 653 | | isGenerativeType work_rhs -- See (CF5) in Note [Exploiting closed type families]
|
| 647 | 654 | = Stage $
|
| ... | ... | @@ -679,39 +686,46 @@ hasRelevantGiven eqs_for_me work_args (EqCt { eq_rhs = work_rhs }) |
| 679 | 686 | relevant (EqCt { eq_ev = ev, eq_lhs = lhs, eq_rhs = rhs_ty })
|
| 680 | 687 | | isGiven ev
|
| 681 | 688 | , TyFamLHS _ lhs_tys <- lhs
|
| 682 | - = isJust (tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys))
|
|
| 689 | + = isJust (tcUnifyTysForInjectivity Unifying work_tys (rhs_ty:lhs_tys))
|
|
| 683 | 690 | | otherwise
|
| 684 | 691 | = False
|
| 685 | 692 | |
| 686 | 693 | getRelevantBranches :: CoAxiom Branched -> [TcType] -> Xi -> [FunDepEqns]
|
| 687 | 694 | -- Return the FunDepEqns that arise from each relevant branch
|
| 695 | +-- Implements Note [Relevance]
|
|
| 688 | 696 | getRelevantBranches ax work_args work_rhs
|
| 689 | - = go [] (fromBranches (coAxiomBranches ax))
|
|
| 697 | + = go (fromBranches (coAxiomBranches ax))
|
|
| 690 | 698 | where
|
| 691 | 699 | work_tys = work_rhs : work_args
|
| 692 | 700 | |
| 693 | - go _ [] = []
|
|
| 694 | - go preceding (branch:branches)
|
|
| 701 | + go [] = []
|
|
| 702 | + go (branch:branches)
|
|
| 695 | 703 | = case is_relevant branch of
|
| 696 | - Just eqn -> eqn : go (branch:preceding) branches
|
|
| 697 | - Nothing -> go (branch:preceding) branches
|
|
| 704 | + Just eqn -> eqn : go branches
|
|
| 705 | + Nothing -> go branches
|
|
| 698 | 706 | where
|
| 699 | - is_relevant (CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys, cab_rhs = rhs_ty })
|
|
| 700 | - | Just subst <- tcUnifyTysForInjectivity True (rhs_ty:lhs_tys) work_tys
|
|
| 701 | - , let (subst', qtvs') = trim_qtvs subst qtvs
|
|
| 702 | - lhs_tys' = substTys subst' lhs_tys
|
|
| 703 | - rhs_ty' = substTy subst' rhs_ty
|
|
| 704 | - , all (no_match lhs_tys') preceding
|
|
| 707 | + is_relevant branch@(CoAxBranch { cab_tvs = qtvs
|
|
| 708 | + , cab_lhs = lhs_tys
|
|
| 709 | + , cab_rhs = rhs_ty })
|
|
| 710 | + | Just subst <- tcUnifyTysForInjectivity Unifying (rhs_ty:lhs_tys) work_tys
|
|
| 711 | + -- See (RW1)-(RW3) in Note [Relevance]
|
|
| 712 | + -- This is a pre-/unification/ check (not matching)
|
|
| 713 | + -- so `subst` can bind both `qtvs` and fvs(work_tys)
|
|
| 714 | + , let (subst',qtvs') = trim_qtvs subst qtvs
|
|
| 715 | + lhs_tys' = substTys subst' lhs_tys
|
|
| 716 | + rhs_ty' = substTy subst' rhs_ty
|
|
| 717 | + branch_tys' = rhs_ty' : lhs_tys'
|
|
| 718 | + , noEarlierMatchCheck lhs_tys' branch -- See (RW4) in Note [Relevance]
|
|
| 705 | 719 | = Just (FDEqns { fd_qtvs = qtvs'
|
| 706 | - , fd_eqs = zipWith Pair (rhs_ty':lhs_tys') work_tys })
|
|
| 720 | + , fd_eqs = zipWith Pair branch_tys' work_tys })
|
|
| 721 | + -- Do not apply the substition to `work_tys`;
|
|
| 722 | + -- See (CF7) in Note [Exploiting closed type families]
|
|
| 707 | 723 | | otherwise
|
| 708 | 724 | = Nothing
|
| 709 | 725 | |
| 710 | - no_match lhs_tys (CoAxBranch { cab_lhs = lhs_tys1 })
|
|
| 711 | - = isNothing (tcUnifyTysForInjectivity False lhs_tys1 lhs_tys)
|
|
| 712 | - |
|
| 713 | 726 | mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> EqCt -> TcS [FunDepEqns]
|
| 714 | --- Implements (INJFAM:Wanted/top)
|
|
| 727 | +-- Implements (INJFAM:Wanted/top-open)
|
|
| 728 | +-- See Note [Exploiting open type families]
|
|
| 715 | 729 | mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs })
|
| 716 | 730 | = do { fam_envs <- getFamInstEnvs
|
| 717 | 731 | ; let branches :: [CoAxBranch]
|
| ... | ... | @@ -720,15 +734,15 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs }) |
| 720 | 734 | ; return (mapMaybe do_one branches) }
|
| 721 | 735 | where
|
| 722 | 736 | do_one :: CoAxBranch -> Maybe FunDepEqns
|
| 723 | - do_one branch@(CoAxBranch { cab_tvs = branch_tvs
|
|
| 724 | - , cab_lhs = branch_lhs_tys
|
|
| 725 | - , cab_rhs = branch_rhs })
|
|
| 726 | - | Just subst <- tcUnifyTysForInjectivity False [branch_rhs] [work_rhs]
|
|
| 727 | - -- False: matching, not unifying
|
|
| 728 | - , let (subst', qtvs) = trim_qtvs subst branch_tvs
|
|
| 737 | + do_one (CoAxBranch { cab_tvs = branch_qtvs
|
|
| 738 | + , cab_lhs = branch_lhs_tys
|
|
| 739 | + , cab_rhs = branch_rhs })
|
|
| 740 | + | Just subst <- tcUnifyTysForInjectivity Matching [branch_rhs] [work_rhs]
|
|
| 741 | + , let (subst', qtvs') = trim_qtvs subst branch_qtvs
|
|
| 729 | 742 | branch_lhs_tys' = substTys subst' branch_lhs_tys
|
| 730 | - , apartnessCheck branch_lhs_tys' branch -- See (TIF3)
|
|
| 731 | - = Just (mkInjectivityFDEqn inj_flags qtvs branch_lhs_tys' work_args)
|
|
| 743 | + -- No need for an apartness check here; for open type families
|
|
| 744 | + -- there are no "preceding" equations
|
|
| 745 | + = Just (mkInjectivityFDEqn inj_flags qtvs' branch_lhs_tys' work_args)
|
|
| 732 | 746 | |
| 733 | 747 | | otherwise
|
| 734 | 748 | = Nothing
|
| ... | ... | @@ -736,7 +750,7 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs }) |
| 736 | 750 | mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> SolverStage [FunDepEqns]
|
| 737 | 751 | -- Wanted constraints only
|
| 738 | 752 | -- Both open and closed type families, but only ones with declared injectivity
|
| 739 | --- See Note [Type inference for type families with injectivity] esp (TIF2)
|
|
| 753 | +-- See Note [Exploiting local type-family injectivity]
|
|
| 740 | 754 | mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
|
| 741 | 755 | = do { let -- eqns_from_inerts: see (INJFAM:Wanted/other)
|
| 742 | 756 | eqns_from_inerts = mapMaybe do_one eqs_for_me
|
| ... | ... | @@ -755,15 +769,23 @@ mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs |
| 755 | 769 | |
| 756 | 770 | mk_eqn iargs = mkInjectivityFDEqn inj_flags [] work_args iargs
|
| 757 | 771 | |
| 758 | -trim_qtvs :: Subst -> [TcTyVar] -> (Subst,[TcTyVar])
|
|
| 759 | --- Tricky stuff: see (TIF1) in
|
|
| 760 | --- Note [Type inference for type families with injectivity]
|
|
| 761 | -trim_qtvs subst [] = (subst, [])
|
|
| 762 | -trim_qtvs subst (tv:tvs)
|
|
| 763 | - | tv `elemSubst` subst = trim_qtvs subst tvs
|
|
| 764 | - | otherwise = let !(subst1, tv') = substTyVarBndr subst tv
|
|
| 765 | - !(subst', tvs') = trim_qtvs subst1 tvs
|
|
| 766 | - in (subst', tv':tvs')
|
|
| 772 | +trim_qtvs :: Subst -> [TyVar] -> (Subst, [TyVar])
|
|
| 773 | +-- Tricky stuff: see (OF1) in Note [Exploiting open type families]
|
|
| 774 | +-- The returned substitution is identical to the incoming one, except that
|
|
| 775 | +-- its in-scope set is extended with the returned [TyVar]
|
|
| 776 | +trim_qtvs unif_subst qtvs
|
|
| 777 | + = go unif_subst qtvs
|
|
| 778 | + where
|
|
| 779 | + go :: Subst -> [TyVar] -> (Subst, [TyVar])
|
|
| 780 | + go subst [] = (subst, [])
|
|
| 781 | + go subst (tv:tvs)
|
|
| 782 | + | tv `elemSubst` unif_subst = go subst tvs
|
|
| 783 | + | otherwise = (subst'', tv':tvs')
|
|
| 784 | + where
|
|
| 785 | + tv' = tv `setTyVarKind` substTy subst (tyVarKind tv)
|
|
| 786 | + subst' = subst `extendSubstInScope` tv'
|
|
| 787 | + !(subst'', tvs') = go subst' tvs
|
|
| 788 | + |
|
| 767 | 789 | |
| 768 | 790 | -----------------------------------------
|
| 769 | 791 | -- Built-in type families
|
| ... | ... | @@ -924,15 +946,20 @@ we attempt to exploit injectivity, via `mkLocalFamEqFDs`: |
| 924 | 946 | * (INJFAM:Wanted/other) see `mkLocalFamEqFDs`
|
| 925 | 947 | work item: [W] F s1 s2 ~ rhs -- Wanted
|
| 926 | 948 | inert: [G/W] F t2 t2 ~ rhs -- Same `rhs`, Given or Wanted
|
| 927 | - We can generate FunDepEqns: (s2 ~ t2)
|
|
| 949 | + See Note [Exploiting local type-family injectivity]
|
|
| 950 | + |
|
| 951 | +* (INJFAM:Wanted/top-open) for open type families: `mkTopOpenFamEqFDs`
|
|
| 952 | + type family F a b = r | r -> b
|
|
| 953 | + type instance F Int (Maybe a) = [G Int] -- G is a type family
|
|
| 954 | + [W] F alpha beta = [ty]
|
|
| 955 | + We can generate (Maybe gamma ~ beta)
|
|
| 956 | + See Note [Exploiting open type families]
|
|
| 928 | 957 | |
| 929 | -* (INJFAM:Wanted/top) see `mkTopUserFamEqFDs`
|
|
| 930 | - work item: [W] F s1 s2 ~ rhs
|
|
| 931 | - type instance forall a b c. F t1 t2 ~ top_rhs
|
|
| 932 | - and we can /match/ the LHS, so that
|
|
| 933 | - S(top_rhs) = rhs
|
|
| 934 | - then we can generate the FunDepEqns: forall a c. s2 ~ S(t2)
|
|
| 935 | - But see wrinkle (TIF1), (TIF3)
|
|
| 958 | +* (INJFAM:Wanted/top-closed) for closed type families: `mkTopClosedFamEqFDs`
|
|
| 959 | + type family F a b where { ...eqns... }
|
|
| 960 | + [W] F alpha ~ Int
|
|
| 961 | + We may be able to generate some extra equalities to constraint `alpha`
|
|
| 962 | + See very clever Note [Exploiting closed type families]
|
|
| 936 | 963 | |
| 937 | 964 | For /built-in/ type families, it's pretty similar, except that
|
| 938 | 965 | |
| ... | ... | @@ -945,45 +972,36 @@ For /built-in/ type families, it's pretty similar, except that |
| 945 | 972 | * mkLocalBuiltinFamEqFDs
|
| 946 | 973 | * mkTopBuiltinFamEqFDs
|
| 947 | 974 | |
| 948 | -(TIF1) Generating fundeps from a top-level type instance is covered in
|
|
| 949 | - Section 5.2 in the Injective Type Families paper. It's a bit tricky.
|
|
| 950 | - Consider
|
|
| 951 | - type family F @k (a::k) (b::k) = r | r -> k b
|
|
| 952 | - type instance forall k (a::k) (b::k). F @k (Proxy @k a) (Proxy @k b) = Proxy @k a
|
|
| 953 | - [W] F @kappa alpha beta ~ Maybe (Proxy @kappa (delta::kappa))
|
|
| 975 | +Note [Exploiting local type-family injectivity] see `mkLocalFamEqFDs`
|
|
| 976 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 977 | +Suppose we have a type family with declared injectivity:
|
|
| 978 | + type family F a b = r | r -> b
|
|
| 979 | +and we have
|
|
| 980 | + work item: [W] F s1 s2 ~ F t1 t2
|
|
| 981 | +or
|
|
| 982 | + work item: [W] F s1 s2 ~ rhs -- Wanted
|
|
| 983 | + inert: [G/W] F t2 t2 ~ rhs -- Same `rhs`, Given or Wanted
|
|
| 954 | 984 | |
| 955 | - we match (Proxy @kappa delta) against the template (Proxy k a), succeeding
|
|
| 956 | - with substitution [k:->kappa, a:->delta]. We want to generate this FunDepEqns
|
|
| 957 | - FDEqn { fd_qtvs = [b:kappa], fd_eqs = [ beta ~ Proxy @kappa b ] }
|
|
| 958 | - Notice that
|
|
| 959 | - * we must quantify the FunDepEqns over `b`, which is not matched; for this
|
|
| 960 | - we will generate a fresh unification variable in `instantiateFunDepEqn`.
|
|
| 961 | - * we must substitute `k:->kappa` in the kind of `b`.
|
|
| 962 | - This fancy footwork for `fd_qtvs` is done by `trim_qtvs` in
|
|
| 963 | - `mkInjWantedFamEqTopEqns`.
|
|
| 985 | +Then we can generate FunDepEqns: (s2 ~ t2)
|
|
| 986 | + |
|
| 987 | +This applies equally to /closed/ type families; it is /not/ subsumed
|
|
| 988 | +by Note [Exploiting closed type families]. Consider:
|
|
| 964 | 989 | |
| 965 | -(TIF2) All this applies equally to /closed/ type families; it is /not/
|
|
| 966 | - subsumed by Note [Exploiting closed type families]. Consider:
|
|
| 967 | 990 | type family F a | r -> a where { .... }
|
| 968 | 991 | |
| 969 | 992 | [W] F t1 ~ a
|
| 970 | 993 | [W] F t2 ~ a
|
| 971 | 994 | |
| 972 | - Then since F is declared injective, we can generate t1~t2.
|
|
| 995 | +Then since F is declared injective, we can generate t1~t2.
|
|
| 973 | 996 | |
| 974 | - As for open type families, we insist on /user-declared/ injectivity only; we
|
|
| 975 | - don't try to /infer/ injectivity even for a closed family. See Section 3.4
|
|
| 976 | - of the "Injective type families" paper. (Arguably, we could /infer/
|
|
| 977 | - injectivity for closed type families, and that would be more in the spirit of
|
|
| 978 | - Note [Exploiting closed type families].)
|
|
| 997 | +As for open type families, we insist on /user-declared/ injectivity only; we
|
|
| 998 | +don't try to /infer/ injectivity even for a closed family. See Section 3.4
|
|
| 999 | +of the "Injective type families" paper. (Arguably, we could /infer/
|
|
| 1000 | +injectivity for closed type families, and that would be more in the spirit of
|
|
| 1001 | +Note [Exploiting closed type families].)
|
|
| 979 | 1002 | |
| 980 | -(TIF3) Further to (TIF1), if we are considering a /closed/ type family, we
|
|
| 981 | - must ensure (see Section 5.2 of the paper) that after matching that
|
|
| 982 | - equation would indeed be the one to fire. So we call `apartnessCheck`
|
|
| 983 | - on the branch to ensure this, in `mkTopUserFamEqFDs`.
|
|
| 984 | - |
|
| 985 | -Definition [Relevance]
|
|
| 986 | -~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1003 | +Note [Relevance]
|
|
| 1004 | +~~~~~~~~~~~~~~~~
|
|
| 987 | 1005 | We say that a closed-type-family equation `F lhs = rhs` is
|
| 988 | 1006 | /relevant/ for a Wanted [W] F wlhs ~ wrhs
|
| 989 | 1007 | iff
|
| ... | ... | @@ -992,6 +1010,10 @@ iff |
| 992 | 1010 | |
| 993 | 1011 | (R2) There is no earlier equation that matches S(lhs). See (RW4) below.
|
| 994 | 1012 | |
| 1013 | +The relevance check is implemented by `getRelevantBranches`, which acutally
|
|
| 1014 | +returns the [FunDepEqns] described in the Closed Family Fundep Algorithm in
|
|
| 1015 | +Note [Exploiting closed type families].
|
|
| 1016 | + |
|
| 995 | 1017 | (RW1) Pre-unification treats type-family applications as binding to anything,
|
| 996 | 1018 | rather like type variables. If two types don't even pre-unify, we say that they
|
| 997 | 1019 | are /apart/. It is done by `tcUnifyTysForInjectivity`.
|
| ... | ... | @@ -1014,24 +1036,82 @@ iff |
| 1014 | 1036 | Clearly the RHS is apart from the first equation and we want to fire injectivity
|
| 1015 | 1037 | on the second equation.
|
| 1016 | 1038 | |
| 1017 | -(RW4) Why "no earlier equation matches" in conditoin (R2)? Consider the family
|
|
| 1039 | +(RW4) Why "no earlier equation matches" in condition (R2)? Consider the family
|
|
| 1018 | 1040 | |
| 1019 | 1041 | type family Bak a = r where
|
| 1020 | 1042 | Bak Int = Char -- B1
|
| 1021 | 1043 | Bak Char = Int -- B2
|
| 1022 | 1044 | Bak a = a -- B3
|
| 1023 | 1045 | |
| 1024 | - and [W] Bak alpha ~ Char. In fact, only (B2) is relevant for this Wanted.
|
|
| 1046 | + and [W] Bak alpha ~ Char. In fact, only (B1) is relevant for this Wanted.
|
|
| 1025 | 1047 | You might think that (B3) could be instantiated to Bak Char ~ Char; but
|
| 1026 | 1048 | actually that instantiation will never fire because (B2) Bak Char ~ Int would
|
| 1027 | - fire first. So the only way to return a Char is if the argment is Int; so we
|
|
| 1049 | + fire first. So the only way to return a Char is via (B1); so we
|
|
| 1028 | 1050 | can emit [W] alpha ~ Int. Hence (B3) is not relevant; only (B2) is relevant.
|
| 1029 | 1051 | |
| 1030 | 1052 | That is the reason for condition (R2) in the definition of Relevance above.
|
| 1031 | 1053 | A watertight proof that this is the Right Thing is not very easy. See more
|
| 1032 | - discussion in #23162.
|
|
| 1054 | + discussion in #23162, and Section 5.2 of the paper.
|
|
| 1033 | 1055 | |
| 1034 | -Note [Exploiting closed type families]
|
|
| 1056 | + How, precisely, do we implement (R2)? We check that there is no earlier equation
|
|
| 1057 | + that fires on S(lhs), in this case (on Bak Char). Notice that this is different
|
|
| 1058 | + from the `apartnessCheck`, which checks that all preceding equations are apart
|
|
| 1059 | + from S(lhs). Apartness checking uses /unification/; here we want /matching/.
|
|
| 1060 | + Hence using `noEarlierMatchCheck`, not `apartnessCheck`.
|
|
| 1061 | + |
|
| 1062 | + Here's a good example from T27171_aux. T
|
|
| 1063 | + type family TMessage m where
|
|
| 1064 | + {- T1 -} TMessage @f @t (CustomMethod s :: Method f t) = ()
|
|
| 1065 | + {- T2 -} TMessage @f @Req (m :: Method f Req) = TRequestMessage m
|
|
| 1066 | + {- T3 -} TMessage @f @Not (m :: Method f Not) = TNotificationMessage m
|
|
| 1067 | + |
|
| 1068 | + [W] TMessage @SC @Req alpha ~# TRequestMessage alpha
|
|
| 1069 | + |
|
| 1070 | + There is only one relevant equation, namely (T2). If we apply its
|
|
| 1071 | + pre-unification substitution [f :-> SC, m :-> alpha] to its LHS we get
|
|
| 1072 | + TMessage @SC @Req alpha
|
|
| 1073 | + and equation (T1) does not match that. (It does unify, but we don't care.)
|
|
| 1074 | + |
|
| 1075 | +Note [Exploiting open type families] see `mkTopOpenFamEqFDs`
|
|
| 1076 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1077 | +Generating fundeps from a top-level type instance is covered in Section 5.2 in
|
|
| 1078 | +the Injective Type Families paper. For open type families, suppose we have
|
|
| 1079 | + |
|
| 1080 | + type family F a b = r | r -> b
|
|
| 1081 | + type instance F Int (Maybe a) = [G Int] -- G is a type family
|
|
| 1082 | + |
|
| 1083 | + [W] F alpha beta = [ty]
|
|
| 1084 | + |
|
| 1085 | +Then, since F has been checked as injective, and the RHS [G Int]
|
|
| 1086 | +pre-unifies with [ty], we can add a derived FunDepEqns
|
|
| 1087 | + FDEqns{ fd_qtvs = a, fd_eqs = [ Maybe a ~ beta ] }
|
|
| 1088 | +and thereby emit
|
|
| 1089 | + [W] Maybe gamma ~ beta -- Fresh gamma
|
|
| 1090 | + |
|
| 1091 | +Wrinkles
|
|
| 1092 | + |
|
| 1093 | +(OF1) Consider
|
|
| 1094 | + type family F @k (a::k) (b::k) = r | r -> k b
|
|
| 1095 | + type instance forall k (a::k) (b::k).
|
|
| 1096 | + F @k (Proxy @k a) (Proxy @k b) = Maybe (Proxy @k a)
|
|
| 1097 | + |
|
| 1098 | + [W] F @kappa alpha beta ~ Maybe (Proxy @kappa (delta::kappa))
|
|
| 1099 | + |
|
| 1100 | + We match the target (Maybe (Proxy @kappa delta))
|
|
| 1101 | + against the template (Maybe (Proxy @k a))
|
|
| 1102 | + succeeding with substitution [k:->kappa, a:->delta]. We want to generate this:
|
|
| 1103 | + FDEqn { fd_qtvs = [b::kappa], fd_eqs = [ Proxy @kappa b ] ~ beta }
|
|
| 1104 | + Notice that
|
|
| 1105 | + * we must quantify the FunDepEqns over `b`, which is not matched; for this
|
|
| 1106 | + we will generate a fresh unification variable in `instantiateFunDepEqn`.
|
|
| 1107 | + * we must substitute `k:->kappa` in the kind of `b`.
|
|
| 1108 | + |
|
| 1109 | + This fancy footwork for `fd_qtvs` is done by `trim_qtvs`. It
|
|
| 1110 | + * Drops a quantified tyvar that /is/ matched
|
|
| 1111 | + * Substitutes in the kind of a quantified tyvar that is /not/ matched
|
|
| 1112 | + * Adds the not-matched tyvar to the in-scope set of the substitution
|
|
| 1113 | + |
|
| 1114 | +Note [Exploiting closed type families] see `mkTopClosedFamEqFDs`
|
|
| 1035 | 1115 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1036 | 1116 | Suppose we have
|
| 1037 | 1117 | type family F a b where
|
| ... | ... | @@ -1042,17 +1122,18 @@ Suppose we have |
| 1042 | 1122 | [W] F Int alpha ~ Char
|
| 1043 | 1123 | |
| 1044 | 1124 | The /only/ way to solve this Wanted is using (F2), so we can safely unify
|
| 1045 | -alpha:=Char without risking losing any solutions. That is what
|
|
| 1046 | -`mkTopClosedFamEqFDs` does. Ticket #23162 has lots of background detail
|
|
| 1125 | +alpha:=Char without risking losing any solutions. We don't even need any
|
|
| 1126 | +injectivity annotations. Ticket #23162 has lots of background detail.
|
|
| 1047 | 1127 | |
| 1048 | -More precisely, here is the Closed Family Fundep Algorithm (CFFA)
|
|
| 1128 | +More precisely, here is the very clever Closed Family Fundep Algorithm (CFFA)
|
|
| 1049 | 1129 | |
| 1050 | 1130 | IF * F a is a closed type family.
|
| 1051 | 1131 | * We are trying to solve [W] F wlhs ~ wrhs.
|
| 1052 | - * There are no "relevant" Givens [G] F lhs ~ rhs. See (CF1) below.
|
|
| 1053 | - * F has exactly one equation, F lhs = rhs that is "relevant" for that Wanted
|
|
| 1132 | + * There are no "relevant Givens" [G] F lhs ~ rhs. See (CF1) below.
|
|
| 1133 | + * F has exactly one equation, F lhs = rhs that is "relevant" for
|
|
| 1134 | + that Wanted (see Note [Relevance])
|
|
| 1054 | 1135 | THEN
|
| 1055 | - we can emit and solve the fundep equalities:
|
|
| 1136 | + we can emit and solve the fundeps :: [FunDepEqns]:
|
|
| 1056 | 1137 | [W] wlhs1 ~ lhs1
|
| 1057 | 1138 | ...
|
| 1058 | 1139 | [W] wlhsn ~ lhsn
|
| ... | ... | @@ -1060,7 +1141,10 @@ More precisely, here is the Closed Family Fundep Algorithm (CFFA) |
| 1060 | 1141 | with fresh unification vars in lhs and rhs for the quantified variables of the
|
| 1061 | 1142 | equation.
|
| 1062 | 1143 | |
| 1063 | -See Definition [Relevance] for what "relevant" means.
|
|
| 1144 | + Actually we take advantage of the substitution generated by the relevance
|
|
| 1145 | + check, see (CF7) below.
|
|
| 1146 | + |
|
| 1147 | +See Note [Relevance] for what "relevant" means.
|
|
| 1064 | 1148 | We need to take care about non-termination; see (CF3).
|
| 1065 | 1149 | |
| 1066 | 1150 | Key point: equations that are not relevant do not need to be considered for fundeps at all.
|
| ... | ... | @@ -1166,6 +1250,8 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1166 | 1250 | I was looking at non-termination for closed type families, but it's a small
|
| 1167 | 1251 | improvement in general.
|
| 1168 | 1252 | |
| 1253 | + This bale-out is implementedn in `tryFDEqns`.
|
|
| 1254 | + |
|
| 1169 | 1255 | (CF5) Consider (see "Yikes5" in #23162):
|
| 1170 | 1256 | type family F a where
|
| 1171 | 1257 | F (Just x) = Int
|
| ... | ... | @@ -1196,7 +1282,7 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1196 | 1282 | type family I t = res | res -> t where
|
| 1197 | 1283 | I TInt = Int |> g -- where g :: Type ~# IK k
|
| 1198 | 1284 | and [W] I alpha ~ Int |> g2
|
| 1199 | - Here we definiteily want to take advantage of injectivity.
|
|
| 1285 | + Here we definitely want to take advantage of injectivity.
|
|
| 1200 | 1286 | |
| 1201 | 1287 | (CF6) This machinery can also have a significant positive effect on the size of
|
| 1202 | 1288 | proof terms. For example (simplification of T26426):
|
| ... | ... | @@ -1204,7 +1290,8 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1204 | 1290 | type family (++) a b where { '[] ++ ys = ys; (x:xs) ++ ys = x : (xs ++ ys) }
|
| 1205 | 1291 | type family MapId a where { MapId '[] = '[]; MapId (x:xs) = x : MapId xs }
|
| 1206 | 1292 | |
| 1207 | - app :: (MapId xs ++ MapId ys ~ MapId (xs ++ ys)) => Proxy xs -> Proxy ys -> Proxy (xs ++ ys)
|
|
| 1293 | + app :: (MapId xs ++ MapId ys ~ MapId (xs ++ ys))
|
|
| 1294 | + => Proxy xs -> Proxy ys -> Proxy (xs ++ ys)
|
|
| 1208 | 1295 | |
| 1209 | 1296 | test :: Proxy [ty_1, ..., ty_n]
|
| 1210 | 1297 | test = Proxy @'[ty_1]
|
| ... | ... | @@ -1248,6 +1335,30 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1248 | 1335 | instead of relying on recursively built sub-proof terms, which brings down
|
| 1249 | 1336 | coercion sizes (in certain situations) from O(n^3) to O(n^2).
|
| 1250 | 1337 | |
| 1338 | +(CF7) Relevance. When computing relevance in the Closed Family Fundep Algorithm,
|
|
| 1339 | + for [W] F wlhs1 wlhs2 ~ wrhs, against an equation F lhs1 lhs2 ~ rhs
|
|
| 1340 | + we get back a pre-unifying substitution S that makes the two as equal as poss.
|
|
| 1341 | + Then we use `trim_qtvs` in exactly the same way as in
|
|
| 1342 | + (OF1) of Note [Exploiting closed type families], to generate qtvs' and S'
|
|
| 1343 | + Then we generate
|
|
| 1344 | + FDEqns { fd_qtvs = qtvs', fd_eqs [ S'(lhs1) ~ wlhs1
|
|
| 1345 | + , S'(lhs2) ~ wlhs2
|
|
| 1346 | + , S'(rhs) ~ wrhs ] }
|
|
| 1347 | + Notice that we do /not/ apply S' to wlhs/wrhs. These type contain unification
|
|
| 1348 | + variables that we must actually unify! Example
|
|
| 1349 | + type familiy F a b where
|
|
| 1350 | + F [a] (Maybe b) = (a, G b)
|
|
| 1351 | + [W] F alpha beta ~ (Int, [gamma])
|
|
| 1352 | + Pre-unification gives [alpha :-> [a], beta :-> Maybe b, a :-> Int]
|
|
| 1353 | + This substitution eliminates the quantified variable `a` but not `b`, so we
|
|
| 1354 | + want this:
|
|
| 1355 | + FDEqns { fd_qtvs = [b], fd_eqs [ [Int] ~ alpha
|
|
| 1356 | + , Maybe b ~ beta
|
|
| 1357 | + , (Int,G b) ~ (Int, [gamma]) ] }
|
|
| 1358 | + |
|
| 1359 | + Notice also that by applying the substitution to the template but not to the
|
|
| 1360 | + Wanted, we uphold the `fd_eqs` invariant in `FDEqns` (see its data type decl)
|
|
| 1361 | + |
|
| 1251 | 1362 | Note [Cache-caused loops]
|
| 1252 | 1363 | ~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1253 | 1364 | It is very dangerous to cache a rewritten wanted family equation as 'solved' in
|
| ... | ... | @@ -1340,28 +1451,29 @@ solveFunDeps work_ev fd_eqns |
| 1340 | 1451 | ; uPairsTcM uenv eqs }
|
| 1341 | 1452 | |
| 1342 | 1453 | instantiateFunDepEqns :: FunDepEqns -> TcM [TypeEqn]
|
| 1343 | -instantiateFunDepEqns (FDEqns { fd_qtvs = tvs, fd_eqs = eqs })
|
|
| 1344 | - | null tvs
|
|
| 1454 | +instantiateFunDepEqns (FDEqns { fd_qtvs = qtvs, fd_eqs = eqs })
|
|
| 1455 | + | null qtvs
|
|
| 1345 | 1456 | = return rev_eqs
|
| 1346 | 1457 | | otherwise
|
| 1347 | - = do { TcM.traceTc "instantiateFunDepEqns" (ppr tvs $$ ppr eqs)
|
|
| 1348 | - ; (_, subst) <- instFlexiXTcM emptySubst tvs -- Takes account of kind substitution
|
|
| 1458 | + = do { TcM.traceTc "instantiateFunDepEqns" (ppr qtvs $$ ppr eqs)
|
|
| 1459 | + ; (_, subst) <- instFlexiXTcM emptySubst qtvs -- Takes account of kind substitution
|
|
| 1349 | 1460 | ; return (map (subst_pair subst) rev_eqs) }
|
| 1350 | 1461 | where
|
| 1351 | 1462 | rev_eqs = reverse eqs
|
| 1352 | 1463 | -- (reverse eqs): See Note [Reverse order of fundep equations]
|
| 1353 | 1464 | |
| 1354 | 1465 | subst_pair subst (Pair ty1 ty2)
|
| 1355 | - = Pair (substTyUnchecked subst' ty1) ty2
|
|
| 1466 | + = Pair (substTy subst' ty1) (substTy subst' ty2)
|
|
| 1467 | +-- ToDo not correct!
|
|
| 1356 | 1468 | -- ty2 does not mention fd_qtvs, so no need to subst it.
|
| 1357 | 1469 | -- See GHC.Tc.Instance.Fundeps Note [Improving against instances]
|
| 1358 | - -- Wrinkle (1)
|
|
| 1470 | + -- Wrinkle (IMP1)
|
|
| 1359 | 1471 | where
|
| 1360 | - subst' = extendSubstInScopeSet subst (tyCoVarsOfType ty1)
|
|
| 1472 | + subst' = extendSubstInScopeSet subst (tyCoVarsOfTypes [ty1,ty2])
|
|
| 1361 | 1473 | -- The free vars of ty1 aren't just fd_qtvs: ty1 is the result
|
| 1362 | 1474 | -- of matching with the [W] constraint. So we add its free
|
| 1363 | 1475 | -- vars to InScopeSet, to satisfy substTy's invariants, even
|
| 1364 | - -- though ty1 will never (currently) be a poytype, so this
|
|
| 1476 | + -- though ty1 will never (currently) be a polytype, so this
|
|
| 1365 | 1477 | -- InScopeSet will never be looked at.
|
| 1366 | 1478 | |
| 1367 | 1479 |
| ... | ... | @@ -59,16 +59,16 @@ StgWord hs_xchg32(StgWord x, StgWord val); |
| 59 | 59 | StgWord64 hs_xchg64(StgWord x, StgWord64 val);
|
| 60 | 60 | |
| 61 | 61 | /* rts/prim/bswap.c */
|
| 62 | -StgWord16 hs_bswap16(StgWord16 x);
|
|
| 63 | -StgWord32 hs_bswap32(StgWord32 x);
|
|
| 62 | +StgWord hs_bswap16(StgWord x);
|
|
| 63 | +StgWord hs_bswap32(StgWord x);
|
|
| 64 | 64 | StgWord64 hs_bswap64(StgWord64 x);
|
| 65 | 65 | |
| 66 | 66 | /* rts/prim/bitrev.c
|
| 67 | 67 | This was done as part of issue #16164.
|
| 68 | 68 | See Note [Bit reversal primop] for more details about the implementation.*/
|
| 69 | 69 | StgWord hs_bitrev8(StgWord x);
|
| 70 | -StgWord16 hs_bitrev16(StgWord16 x);
|
|
| 71 | -StgWord32 hs_bitrev32(StgWord32 x);
|
|
| 70 | +StgWord hs_bitrev16(StgWord x);
|
|
| 71 | +StgWord hs_bitrev32(StgWord x);
|
|
| 72 | 72 | StgWord64 hs_bitrev64(StgWord64 x);
|
| 73 | 73 | |
| 74 | 74 | /* rts/prim/longlong.c */
|
| ... | ... | @@ -36,8 +36,8 @@ hs_bitrev8(StgWord x) |
| 36 | 36 | return x;
|
| 37 | 37 | }
|
| 38 | 38 | |
| 39 | -StgWord16
|
|
| 40 | -hs_bitrev16(StgWord16 x)
|
|
| 39 | +StgWord
|
|
| 40 | +hs_bitrev16(StgWord x)
|
|
| 41 | 41 | {
|
| 42 | 42 | x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1 );
|
| 43 | 43 | x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2 );
|
| ... | ... | @@ -46,14 +46,14 @@ hs_bitrev16(StgWord16 x) |
| 46 | 46 | return x;
|
| 47 | 47 | }
|
| 48 | 48 | |
| 49 | -StgWord32
|
|
| 50 | -hs_bitrev32(StgWord32 x)
|
|
| 49 | +StgWord
|
|
| 50 | +hs_bitrev32(StgWord x)
|
|
| 51 | 51 | {
|
| 52 | - x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1 );
|
|
| 53 | - x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2 );
|
|
| 54 | - x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4 );
|
|
| 55 | - x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8 );
|
|
| 56 | - x = ( x >> 16 ) | ( x << 16 );
|
|
| 52 | + x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1 );
|
|
| 53 | + x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2 );
|
|
| 54 | + x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4 );
|
|
| 55 | + x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8 );
|
|
| 56 | + x = ((x >> 16) & 0x0000FFFF) | ((x & 0x0000FFFF) << 16);
|
|
| 57 | 57 | return x;
|
| 58 | 58 | }
|
| 59 | 59 |
| 1 | 1 | #include "Rts.h"
|
| 2 | 2 | |
| 3 | -StgWord16
|
|
| 4 | -hs_bswap16(StgWord16 x)
|
|
| 3 | +StgWord
|
|
| 4 | +hs_bswap16(StgWord x)
|
|
| 5 | 5 | {
|
| 6 | - return ((x >> 8) | (x << 8));
|
|
| 6 | + x = (StgWord16)x;
|
|
| 7 | + return (StgWord16)((x >> 8) | (x << 8));
|
|
| 7 | 8 | }
|
| 8 | 9 | |
| 9 | -StgWord32
|
|
| 10 | -hs_bswap32(StgWord32 x)
|
|
| 10 | +StgWord
|
|
| 11 | +hs_bswap32(StgWord x)
|
|
| 11 | 12 | {
|
| 12 | - return ((x >> 24) | ((x >> 8) & 0xff00) |
|
|
| 13 | - (x << 24) | ((x & 0xff00) << 8));
|
|
| 13 | + x = (StgWord32)x;
|
|
| 14 | + return (StgWord32)((x >> 24) | ((x >> 8) & 0xff00) |
|
|
| 15 | + (x << 24) | ((x & 0xff00) << 8));
|
|
| 14 | 16 | }
|
| 15 | 17 | |
| 16 | 18 | StgWord64
|
| 1 | +TOP=../../..
|
|
| 2 | +include $(TOP)/mk/boilerplate.mk
|
|
| 3 | +include $(TOP)/mk/test.mk |
| 1 | +module M (T (..)) where
|
|
| 2 | + |
|
| 3 | +newtype T = MkT Int
|
|
| 4 | + deriving (Eq, Ord) |
| 1 | +test('prog-mhu008',
|
|
| 2 | + [extra_files(['a/', 'b/', 'unitA', 'unitB']),
|
|
| 3 | + cmd_prefix('ghciWayFlags=' + config.ghci_way_flags),
|
|
| 4 | + req_interp],
|
|
| 5 | + ghci_multiunit_script, [['unitA', 'unitB'], 'prog-mhu008.script']) |
| 1 | +{-# LANGUAGE PackageImports #-}
|
|
| 2 | + |
|
| 3 | +module M
|
|
| 4 | + ( module Export
|
|
| 5 | + , cmp
|
|
| 6 | + ) where
|
|
| 7 | + |
|
| 8 | +import "a" M as Export
|
|
| 9 | + |
|
| 10 | +cmp :: T -> T -> Bool
|
|
| 11 | +cmp x y = x <= y |
| 1 | +:set -XPackageImports
|
|
| 2 | +import "a" M qualified as MA
|
|
| 3 | +import "b" M qualified as MB
|
|
| 4 | + |
|
| 5 | +MB.cmp (MA.MkT 1) (MA.MkT 2) |
| 1 | +True |
| 1 | +-this-unit-id a-0-inplace
|
|
| 2 | +-this-package-name a
|
|
| 3 | +-i
|
|
| 4 | +-ia
|
|
| 5 | +M |
| 1 | +-this-unit-id b-0-inplace
|
|
| 2 | +-this-package-name b
|
|
| 3 | +-package-id a-0-inplace
|
|
| 4 | +-i
|
|
| 5 | +-ib
|
|
| 6 | +M |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 2 | +{-# LANGUAGE TypeAbstractions #-}
|
|
| 3 | +{-# LANGUAGE TypeFamilies #-}
|
|
| 4 | +{-# LANGUAGE UndecidableInstances #-}
|
|
| 5 | +module Bug where
|
|
| 6 | + |
|
| 7 | +import Data.Functor.Identity (Identity(..))
|
|
| 8 | +import Data.Kind (Type)
|
|
| 9 | +import Data.Proxy (Proxy(..))
|
|
| 10 | +import Data.Type.Equality ((:~:)(..))
|
|
| 11 | + |
|
| 12 | +type TyFun :: Type -> Type -> Type
|
|
| 13 | +data TyFun a b
|
|
| 14 | + |
|
| 15 | +type (~>) :: Type -> Type -> Type
|
|
| 16 | +type a ~> b = TyFun a b -> Type
|
|
| 17 | +infixr 0 ~>
|
|
| 18 | + |
|
| 19 | +type Apply :: (k1 ~> k2) -> k1 -> k2
|
|
| 20 | +type family Apply f x
|
|
| 21 | + |
|
| 22 | +type Rep1 :: (k -> Type) -> k -> Type
|
|
| 23 | +type family Rep1 f
|
|
| 24 | + |
|
| 25 | +type To1 :: Rep1 f a -> f a
|
|
| 26 | +type family To1 z
|
|
| 27 | + |
|
| 28 | +type Par1 :: Type -> Type
|
|
| 29 | +newtype Par1 p = Par1 p
|
|
| 30 | + |
|
| 31 | +type To1Sym0 :: forall k (f :: k -> Type) (a :: k). Rep1 f a ~> f a
|
|
| 32 | +data To1Sym0 z
|
|
| 33 | + |
|
| 34 | +applyTo1Sym0 :: forall k (f :: k -> Type) (a :: k) (x :: Rep1 f a). Proxy x -> Apply @(Rep1 f a) @(f a) To1Sym0 x :~: To1 x
|
|
| 35 | +applyTo1Sym0 _ = undefined
|
|
| 36 | + |
|
| 37 | +type IdentitySym0 :: a ~> Identity a
|
|
| 38 | +data IdentitySym0 z
|
|
| 39 | +type instance Apply IdentitySym0 x = 'Identity x
|
|
| 40 | + |
|
| 41 | +type Aux :: Rep1 Identity a -> Rep1 Identity a -> Identity a
|
|
| 42 | +type family Aux x y where
|
|
| 43 | + Aux x ('Par1 wombat) = Apply IdentitySym0 wombat
|
|
| 44 | + |
|
| 45 | +type instance Rep1 Identity = Par1
|
|
| 46 | +type instance To1 @Identity y = Aux y y
|
|
| 47 | + |
|
| 48 | +lemma :: forall a (z :: a). Apply @(Rep1 Identity a) @(Identity a) To1Sym0 ('Par1 z) :~: 'Identity z
|
|
| 49 | +lemma = applyTo1Sym0 @Type @Identity @a (Proxy @('Par1 z))
|
|
| 50 | +-- lemma = applyTo1Sym0 @Type @Identity @a @('Par1 z) (Proxy @('Par1 z)) |
| ... | ... | @@ -316,3 +316,4 @@ test('T25611b', normal, compile, ['']) |
| 316 | 316 | test('T25611c', normal, compile, [''])
|
| 317 | 317 | test('T25611d', normal, compile, [''])
|
| 318 | 318 | test('T25657', normal, compile, [''])
|
| 319 | +test('T27828', normal, compile, ['']) |
| 1 | +{-# LANGUAGE MagicHash #-}
|
|
| 2 | +import GHC.Exts
|
|
| 3 | +import GHC.Word
|
|
| 4 | +import Numeric
|
|
| 5 | + |
|
| 6 | +main :: IO ()
|
|
| 7 | +main = do
|
|
| 8 | + putStrLn $ showHex (W# (bitReverse8# 0x55##)) ""
|
|
| 9 | + putStrLn $ showHex (W# (bitReverse8# 0xAA##)) ""
|
|
| 10 | + putStrLn $ showHex (W# (bitReverse16# 0x5555##)) ""
|
|
| 11 | + putStrLn $ showHex (W# (bitReverse16# 0xAAAA##)) ""
|
|
| 12 | + putStrLn $ showHex (W# (bitReverse32# 0x5555_5555##)) ""
|
|
| 13 | + putStrLn $ showHex (W# (bitReverse32# 0xAAAA_AAAA##)) ""
|
|
| 14 | + putStrLn $ showHex (W# (byteSwap16# 0xABCD##)) ""
|
|
| 15 | + putStrLn $ showHex (W# (byteSwap32# 0xABCD_EF12##)) ""
|
|
| 16 | + putStrLn $ showHex (W# (noinline bitReverse8# 0x55##)) ""
|
|
| 17 | + putStrLn $ showHex (W# (noinline bitReverse8# 0xAA##)) ""
|
|
| 18 | + putStrLn $ showHex (W# (noinline bitReverse16# 0x5555##)) ""
|
|
| 19 | + putStrLn $ showHex (W# (noinline bitReverse16# 0xAAAA##)) ""
|
|
| 20 | + putStrLn $ showHex (W# (noinline bitReverse32# 0x5555_5555##)) ""
|
|
| 21 | + putStrLn $ showHex (W# (noinline bitReverse32# 0xAAAA_AAAA##)) ""
|
|
| 22 | + putStrLn $ showHex (W# (noinline byteSwap16# 0xABCD##)) ""
|
|
| 23 | + putStrLn $ showHex (W# (noinline byteSwap32# 0xABCD_EF12##)) "" |
| 1 | +aa
|
|
| 2 | +55
|
|
| 3 | +aaaa
|
|
| 4 | +5555
|
|
| 5 | +aaaaaaaa
|
|
| 6 | +55555555
|
|
| 7 | +cdab
|
|
| 8 | +12efcdab
|
|
| 9 | +aa
|
|
| 10 | +55
|
|
| 11 | +aaaa
|
|
| 12 | +5555
|
|
| 13 | +aaaaaaaa
|
|
| 14 | +55555555
|
|
| 15 | +cdab
|
|
| 16 | +12efcdab |
| ... | ... | @@ -91,3 +91,4 @@ test('T24496' |
| 91 | 91 | ]
|
| 92 | 92 | , compile_and_run, ['-O'])
|
| 93 | 93 | test('T6026', normal, compile_and_run, [''])
|
| 94 | +test('T27299', normal, compile_and_run, ['']) |