Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
ec079385
by Simon Peyton Jones at 2026-10-12T18:14:12-04:00
15 changed files:
- + changelog.d/T27828
- compiler/GHC/Builtin/WiredIn/Types/Box.hs
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/TyCl.hs
- + testsuite/tests/indexed-types/should_compile/T27828.hs
- + testsuite/tests/indexed-types/should_compile/T27828a.hs
- + testsuite/tests/indexed-types/should_compile/T27828b.hs
- testsuite/tests/indexed-types/should_compile/all.T
Changes:
| 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 implementation of functional dependencies for type families.
|
|
| 8 | +} |
| ... | ... | @@ -329,7 +329,8 @@ mkWiredInNewTyCon tc_name dc_name nt_co_uniq bndrs roles nt_fld_ty = |
| 329 | 329 | , cab_roles = roles
|
| 330 | 330 | , cab_lhs = mkTyVarTys tvs
|
| 331 | 331 | , cab_rhs = nt_fld_ty
|
| 332 | - , cab_incomps = [] }
|
|
| 332 | + , cab_overlaps = []
|
|
| 333 | + , cab_incomps = [] }
|
|
| 333 | 334 | |
| 334 | 335 | -- | The wired-in @Box@ newtype:
|
| 335 | 336 | --
|
| ... | ... | @@ -18,7 +18,7 @@ module GHC.Core.Coercion.Axiom ( |
| 18 | 18 | coAxiomSingleBranch, coAxBranchTyVars, coAxBranchCoVars,
|
| 19 | 19 | coAxBranchRoles,
|
| 20 | 20 | coAxBranchLHS, coAxBranchRHS, coAxBranchSpan, coAxBranchIncomps,
|
| 21 | - placeHolderIncomps,
|
|
| 21 | + placeHolderIncomps, placeHolderOverlaps,
|
|
| 22 | 22 | |
| 23 | 23 | Role(..),
|
| 24 | 24 | |
| ... | ... | @@ -195,23 +195,44 @@ mapAccumBranches f (MkBranches arr) |
| 195 | 195 | |
| 196 | 196 | Note [Storing compatibility]
|
| 197 | 197 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 198 | -During axiom application, we need to be aware of which branches are compatible
|
|
| 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
|
|
| 201 | -GHC.Core.Coercion.Axiom on the unification algorithm.) Although we could
|
|
| 202 | -theoretically compute compatibility on the fly, this is silly, so we store it
|
|
| 203 | -in a CoAxiom.
|
|
| 198 | +A `CoAxBranch` caches some useful information in `cab_incomps` and `cab_overlaps`:
|
|
| 204 | 199 | |
| 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.
|
|
| 200 | +* `cab_overlaps`: when computing "relevance", in the function
|
|
| 201 | + `GHC.Tc.Solver.FunDeps.getRelevantBranches`, we need to know which ealier branches
|
|
| 202 | + can match this one -- see `noEarlierMatch`.
|
|
| 208 | 203 | |
| 209 | -CoAxBranches that do not (yet) belong to a CoAxiom should have a panic thunk
|
|
| 210 | -stored in cab_incomps. The incompatibilities are properly a property of the
|
|
| 211 | -axiom as a whole, and they are computed only when the final axiom is built.
|
|
| 204 | + Again we could look at all earlier branches, but instead we cache in `cab_overlaps`
|
|
| 205 | + a list of all earlier branches that could overlap with this one.
|
|
| 212 | 206 | |
| 213 | -During serialization, the list is converted into a list of the indices
|
|
| 214 | -of the branches.
|
|
| 207 | +* `cab_incomps`: during axiom application, we need to be aware of which branches are
|
|
| 208 | + /compatible/ with which others. The full explanation is in Note [Compatibility] in
|
|
| 209 | + GHC.Core.FamInstEnv. (The code is placed there to avoid a dependency from
|
|
| 210 | + GHC.Core.Coercion.Axiom on the unification algorithm.)
|
|
| 211 | + |
|
| 212 | + Although we could readily compute compatibility on the fly, this is silly, so we
|
|
| 213 | + cache in `cab_incomps` a list of earlier branches that are /incompatible/ with
|
|
| 214 | + this one. (See Note [Compatibility] for a definition.)
|
|
| 215 | + |
|
| 216 | + Always a sub-list of `cab_overlaps`.
|
|
| 217 | + |
|
| 218 | +Both lists can be empty, and always are for the first branch of any axiom.
|
|
| 219 | + |
|
| 220 | +Some extra points:
|
|
| 221 | + |
|
| 222 | +(SC1) A `CoAxBranch` that does not (yet) belong to a CoAxiom is initialised with panic
|
|
| 223 | + thunks, `placeHolderOverlaps` or `placeHolderIncomps`, for the two fields; see `mkCoAxBranch`.
|
|
| 224 | + |
|
| 225 | + Then, when a bunch of branches is grouped together in an axiom, we analyse the
|
|
| 226 | + branches as a whole and initialise the fields properly, using `computeAxiomIncomps`.
|
|
| 227 | + (For open type families, whose axioms have only one branch, we null out both lists
|
|
| 228 | + with `noAxiomIncomps`.)
|
|
| 229 | + |
|
| 230 | +(SC2) We don't need to serialise `cab_overlaps` and `cab_incomps` into an interface
|
|
| 231 | + file, because we recompute them in `computeAxiomIncomps`. However, annoyingly,
|
|
| 232 | + the pretty printer converts to IfaceSyn before printing, and we do want to show
|
|
| 233 | + `cab_incomps` (see Note [Displaying axiom incompatibilities]). So, tiresomely,
|
|
| 234 | + `IfaceAxBranch` has a `ifaxbIncomps` field, used only for printing. For historical
|
|
| 235 | + reasons this is actually serialised. Yuk.
|
|
| 215 | 236 | |
| 216 | 237 | Note [CoAxioms are homogeneous]
|
| 217 | 238 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -230,7 +251,9 @@ This is checked in FamInstEnv.mkCoAxBranch. |
| 230 | 251 | -- If you edit this type, you may need to update the GHC formalism
|
| 231 | 252 | -- See Note [GHC Formalism] in GHC.Core.Lint
|
| 232 | 253 | data CoAxiom br
|
| 233 | - = CoAxiom -- Type equality axiom.
|
|
| 254 | + = -- `br` is Unbranched for each of the many axioms of an open type family
|
|
| 255 | + -- Branched for the single multi-branch axiom of a closed type family
|
|
| 256 | + CoAxiom -- Type equality axiom.
|
|
| 234 | 257 | { co_ax_unique :: Unique -- Unique identifier
|
| 235 | 258 | , co_ax_name :: Name -- Name for pretty-printing
|
| 236 | 259 | , co_ax_role :: Role -- Role of the axiom's equality
|
| ... | ... | @@ -268,8 +291,15 @@ data CoAxBranch |
| 268 | 291 | , cab_rhs :: Type
|
| 269 | 292 | -- ^ Right-hand side of the equality
|
| 270 | 293 | -- See Note [CoAxioms are homogeneous]
|
| 294 | + |
|
| 295 | + , cab_overlaps :: [CoAxBranch]
|
|
| 296 | + -- ^ The preceding branches whose LHSs are /unify with/ this one
|
|
| 297 | + -- Order is unimportant
|
|
| 298 | + -- See Note [Storing compatibility]
|
|
| 299 | + |
|
| 271 | 300 | , cab_incomps :: [CoAxBranch]
|
| 272 | - -- ^ The previous incompatible branches
|
|
| 301 | + -- ^ The preceding branches that are /incompatible/ with this one
|
|
| 302 | + -- Order is unimportant
|
|
| 273 | 303 | -- See Note [Storing compatibility]
|
| 274 | 304 | }
|
| 275 | 305 | deriving Data.Data
|
| ... | ... | @@ -342,8 +372,9 @@ coAxBranchIncomps :: CoAxBranch -> [CoAxBranch] |
| 342 | 372 | coAxBranchIncomps = cab_incomps
|
| 343 | 373 | |
| 344 | 374 | -- See Note [Compatibility] in GHC.Core.FamInstEnv
|
| 345 | -placeHolderIncomps :: [CoAxBranch]
|
|
| 346 | -placeHolderIncomps = panic "placeHolderIncomps"
|
|
| 375 | +placeHolderIncomps, placeHolderOverlaps :: [CoAxBranch]
|
|
| 376 | +placeHolderIncomps = panic "placeHolderIncomps"
|
|
| 377 | +placeHolderOverlaps = panic "placeHolderOverlaps"
|
|
| 347 | 378 | |
| 348 | 379 | {-
|
| 349 | 380 | Note [CoAxBranch type variables]
|
| ... | ... | @@ -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(..),
|
| ... | ... | @@ -487,20 +487,45 @@ in GHC.Core.Unify.) |
| 487 | 487 | |
| 488 | 488 | Note [Compatibility]
|
| 489 | 489 | ~~~~~~~~~~~~~~~~~~~~
|
| 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.
|
|
| 490 | +Consider a closed type family with two equations (X1) and (X2)
|
|
| 491 | + type family F a where
|
|
| 492 | + F lhs1 = rhs1 -- (X1)
|
|
| 493 | + ...
|
|
| 494 | + F lhs2 = rhs2 -- (X2)
|
|
| 495 | + ...
|
|
| 496 | +Then equations (X1) and (X2) are /compatible/ if any target (F ty) that
|
|
| 497 | +matches both equations yields the very same right hand side. Example:
|
|
| 498 | + And True True = True
|
|
| 499 | + And a True = a
|
|
| 500 | +The target (And True True) matches both equations but they then both
|
|
| 501 | +produce the same reduct True.
|
|
| 502 | + |
|
| 503 | +More precisely (X1) and (X2) are /compatible/ iff
|
|
| 504 | + If LHSs unify with a substitution S, then S(rhs1) = S(rhs2)
|
|
| 505 | + |
|
| 506 | +Conversely, (X1) and (X2) are /incompatible/ if
|
|
| 507 | + Their LHSs unify with S, and S(rhs1) /= S(rhs2)
|
|
| 494 | 508 | |
| 495 | 509 | For open type families, only compatible instances are allowed. For closed
|
| 496 | -type families, the story is slightly more complicated. Consider the following:
|
|
| 510 | +families, we use the Closed Family Matching Rule (see function `findBranch`):
|
|
| 497 | 511 | |
| 498 | -type family F a where
|
|
| 499 | - F Int = Bool
|
|
| 500 | - F a = Int
|
|
| 512 | + When looking up a target (F ty) in a closed type family F,
|
|
| 513 | + find an equation (branch) such that:
|
|
| 514 | + * the LHS matches the target
|
|
| 515 | + * the target is apart from every previous /incompatible/ equation for F
|
|
| 501 | 516 | |
| 502 | -g :: Show a => a -> F a
|
|
| 503 | -g x = length (show x)
|
|
| 517 | +We don't need to check the earlier equations that are compatible with the
|
|
| 518 | +matching equation, because they are either irrelevant (clause 1 of compatible)
|
|
| 519 | +or benign (clause 2 of compatible).
|
|
| 520 | + |
|
| 521 | +Some examples:
|
|
| 522 | + |
|
| 523 | + type family F a where
|
|
| 524 | + F Int = Bool
|
|
| 525 | + F a = Int
|
|
| 526 | + |
|
| 527 | + g :: Show a => a -> F a
|
|
| 528 | + g x = length (show x)
|
|
| 504 | 529 | |
| 505 | 530 | Should that type-check? No. We need to allow for the possibility that 'a'
|
| 506 | 531 | might be Int and therefore 'F a' should be Bool. We can simplify 'F a' to Int
|
| ... | ... | @@ -516,12 +541,12 @@ potentially-overlapping group is closed. |
| 516 | 541 | |
| 517 | 542 | As another example, consider this:
|
| 518 | 543 | |
| 519 | -type family G x where
|
|
| 520 | - G Int = Bool
|
|
| 521 | - G a = Double
|
|
| 544 | + type family G x where
|
|
| 545 | + G Int = Bool
|
|
| 546 | + G a = Double
|
|
| 522 | 547 | |
| 523 | -type family H y
|
|
| 524 | --- no instances
|
|
| 548 | + type family H y
|
|
| 549 | + -- no instances
|
|
| 525 | 550 | |
| 526 | 551 | Now, we want to simplify (G (H Char)). We can't, because (H Char) might later
|
| 527 | 552 | simplify to be Int. So, (G (H Char)) is stuck, for now.
|
| ... | ... | @@ -529,18 +554,13 @@ simplify to be Int. So, (G (H Char)) is stuck, for now. |
| 529 | 554 | While everything above is quite sound, it isn't as expressive as we'd like.
|
| 530 | 555 | Consider this:
|
| 531 | 556 | |
| 532 | -type family J a where
|
|
| 533 | - J Int = Int
|
|
| 534 | - J a = a
|
|
| 557 | + type family J a where
|
|
| 558 | + J Int = Int
|
|
| 559 | + J a = a
|
|
| 535 | 560 | |
| 536 | 561 | Can we simplify (J b) to b? Sure we can. Yes, the first equation matches if
|
| 537 | 562 | b is instantiated with Int, but the RHSs coincide there, so it's all OK.
|
| 538 | - |
|
| 539 | -So, the rule is this: when looking up a branch in a closed type family, we
|
|
| 540 | -find a branch that matches the target, but then we make sure that the target
|
|
| 541 | -is apart from every previous *incompatible* branch. We don't check the
|
|
| 542 | -branches that are compatible with the matching branch, because they are either
|
|
| 543 | -irrelevant (clause 1 of compatible) or benign (clause 2 of compatible).
|
|
| 563 | +Hence the Closed Family Matching Rule.
|
|
| 544 | 564 | |
| 545 | 565 | Note [Compatibility of eta-reduced axioms]
|
| 546 | 566 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -572,15 +592,32 @@ fails anyway. |
| 572 | 592 | |
| 573 | 593 | -- See Note [Compatibility]
|
| 574 | 594 | compatibleBranches :: CoAxBranch -> CoAxBranch -> Bool
|
| 575 | -compatibleBranches (CoAxBranch { cab_lhs = lhs1, cab_rhs = rhs1 })
|
|
| 576 | - (CoAxBranch { cab_lhs = lhs2, cab_rhs = rhs2 })
|
|
| 595 | +compatibleBranches b1 b2
|
|
| 596 | + = case compareBranches b1 b2 of
|
|
| 597 | + BC_Apart -> True
|
|
| 598 | + BC_Compat -> True
|
|
| 599 | + BC_Incompat -> False
|
|
| 600 | + |
|
| 601 | +data BranchCompatibility
|
|
| 602 | + = BC_Apart -- LHSs are apart
|
|
| 603 | + | BC_Compat -- LHSs unify with S, and S(rhs1)=S(rhs2)
|
|
| 604 | + | BC_Incompat -- LHSs unify with S, and S(rhs1)/=S(rhs2)
|
|
| 605 | + |
|
| 606 | +compareBranches :: CoAxBranch -> CoAxBranch -> BranchCompatibility
|
|
| 607 | +compareBranches (CoAxBranch { cab_lhs = lhs1, cab_rhs = rhs1 })
|
|
| 608 | + (CoAxBranch { cab_lhs = lhs2, cab_rhs = rhs2 })
|
|
| 577 | 609 | = case tcUnifyTysFG alwaysBindFam alwaysBindTv commonlhs1 commonlhs2 of
|
| 578 | 610 | -- Here we need the cab_tvs of the two branches to be disinct.
|
| 579 | 611 | -- See Note [CoAxBranch type variables] in GHC.Core.Coercion.Axiom.
|
| 580 | - SurelyApart -> True
|
|
| 581 | - MaybeApart {} -> False
|
|
| 582 | - Unifiable subst -> Type.substTyAddInScope subst rhs1 `eqType`
|
|
| 612 | + SurelyApart -> BC_Apart
|
|
| 613 | + Unifiable subst | Type.substTyAddInScope subst rhs1 `eqType`
|
|
| 583 | 614 | Type.substTyAddInScope subst rhs2
|
| 615 | + -> BC_Compat
|
|
| 616 | + | otherwise
|
|
| 617 | + -> BC_Incompat
|
|
| 618 | + MaybeApart {} -> BC_Incompat
|
|
| 619 | + -- An occurs check yields MaybeApart;
|
|
| 620 | + -- see Note [Infinitary substitutions] in GHC.Core.Unify
|
|
| 584 | 621 | where
|
| 585 | 622 | (commonlhs1, commonlhs2) = zipAndUnzip lhs1 lhs2
|
| 586 | 623 | -- See Note [Compatibility of eta-reduced axioms]
|
| ... | ... | @@ -603,8 +640,7 @@ injectiveBranches injectivity |
| 603 | 640 | ax1@(CoAxBranch { cab_lhs = lhs1, cab_rhs = rhs1 })
|
| 604 | 641 | ax2@(CoAxBranch { cab_lhs = lhs2, cab_rhs = rhs2 })
|
| 605 | 642 | -- See Note [Verifying injectivity annotation], case 1.
|
| 606 | - = case tcUnifyTysForInjectivity True [rhs1] [rhs2] of
|
|
| 607 | - -- True = two-way pre-unification
|
|
| 643 | + = case tcUnifyTysForInjectivity Unifying [rhs1] [rhs2] of
|
|
| 608 | 644 | Nothing -> InjectivityAccepted
|
| 609 | 645 | -- RHS are different, so equations are injective.
|
| 610 | 646 | -- This is case 1A from Note [Verifying injectivity annotation]
|
| ... | ... | @@ -629,10 +665,11 @@ injectiveBranches injectivity |
| 629 | 665 | lhs1Subst = Type.substTys subst (getInjArgs lhs1)
|
| 630 | 666 | lhs2Subst = Type.substTys subst (getInjArgs lhs2)
|
| 631 | 667 | |
| 632 | --- takes a CoAxiom with unknown branch incompatibilities and computes
|
|
| 633 | --- the compatibilities
|
|
| 634 | --- See Note [Storing compatibility] in GHC.Core.Coercion.Axiom
|
|
| 635 | 668 | computeAxiomIncomps :: [CoAxBranch] -> [CoAxBranch]
|
| 669 | +-- Takes a CoAxiom for a closed type family that has place-holder
|
|
| 670 | +-- `cab_incomps` and `cab_overlaps` fields, and computes those fields
|
|
| 671 | +-- properly from the list of branches.
|
|
| 672 | +-- See Note [Storing compatibility] in GHC.Core.Coercion.Axiom
|
|
| 636 | 673 | computeAxiomIncomps branches
|
| 637 | 674 | = snd (mapAccumL go [] branches)
|
| 638 | 675 | where
|
| ... | ... | @@ -640,11 +677,23 @@ computeAxiomIncomps branches |
| 640 | 677 | go prev_brs cur_br
|
| 641 | 678 | = (new_br : prev_brs, new_br)
|
| 642 | 679 | where
|
| 643 | - new_br = cur_br { cab_incomps = mk_incomps prev_brs cur_br }
|
|
| 644 | - |
|
| 645 | - mk_incomps :: [CoAxBranch] -> CoAxBranch -> [CoAxBranch]
|
|
| 646 | - mk_incomps prev_brs cur_br
|
|
| 647 | - = filter (not . compatibleBranches cur_br) prev_brs
|
|
| 680 | + (overlaps,incomps) = get_cab [] [] prev_brs
|
|
| 681 | + new_br = cur_br { cab_overlaps = overlaps, cab_incomps = incomps }
|
|
| 682 | + |
|
| 683 | + get_cab :: [CoAxBranch] -> [CoAxBranch] -- Accumulators
|
|
| 684 | + -> [CoAxBranch]
|
|
| 685 | + -> ([CoAxBranch], [CoAxBranch])
|
|
| 686 | + get_cab overlaps incomps [] = (overlaps,incomps)
|
|
| 687 | + get_cab overlaps incomps (br:brs)
|
|
| 688 | + = case compareBranches cur_br br of
|
|
| 689 | + BC_Apart -> get_cab overlaps incomps brs
|
|
| 690 | + BC_Compat -> get_cab (br:overlaps) incomps brs
|
|
| 691 | + BC_Incompat -> get_cab (br:overlaps) (br:incomps) brs
|
|
| 692 | + |
|
| 693 | +noAxiomIncomps :: CoAxBranch -> CoAxBranch
|
|
| 694 | +-- Overwrite the placeholders for `cab_incomps` and `cab_overlaps`
|
|
| 695 | +-- with [], because unbranched axioms have no "preceding" equations
|
|
| 696 | +noAxiomIncomps branch = branch { cab_incomps = [], cab_overlaps = [] }
|
|
| 648 | 697 | |
| 649 | 698 | {-
|
| 650 | 699 | ************************************************************************
|
| ... | ... | @@ -715,14 +764,17 @@ mkCoAxBranch :: [TyVar] -- original, possibly stale, tyvars |
| 715 | 764 | -> SrcSpan
|
| 716 | 765 | -> CoAxBranch
|
| 717 | 766 | mkCoAxBranch tvs eta_tvs cvs lhs rhs roles loc
|
| 718 | - = CoAxBranch { cab_tvs = tvs'
|
|
| 719 | - , cab_eta_tvs = eta_tvs'
|
|
| 720 | - , cab_cvs = cvs'
|
|
| 721 | - , cab_lhs = tidyTypes env lhs
|
|
| 722 | - , cab_roles = roles
|
|
| 723 | - , cab_rhs = tidyType env rhs
|
|
| 724 | - , cab_loc = loc
|
|
| 725 | - , cab_incomps = placeHolderIncomps }
|
|
| 767 | + = CoAxBranch { cab_tvs = tvs'
|
|
| 768 | + , cab_eta_tvs = eta_tvs'
|
|
| 769 | + , cab_cvs = cvs'
|
|
| 770 | + , cab_lhs = tidyTypes env lhs
|
|
| 771 | + , cab_roles = roles
|
|
| 772 | + , cab_rhs = tidyType env rhs
|
|
| 773 | + , cab_loc = loc
|
|
| 774 | + |
|
| 775 | + -- See (SC1) in Note [Storing compatibility]
|
|
| 776 | + , cab_overlaps = placeHolderOverlaps
|
|
| 777 | + , cab_incomps = placeHolderIncomps }
|
|
| 726 | 778 | where
|
| 727 | 779 | (env1, tvs') = tidyVarBndrs init_tidy_env tvs
|
| 728 | 780 | (env2, eta_tvs') = tidyVarBndrs env1 eta_tvs
|
| ... | ... | @@ -736,14 +788,16 @@ mkCoAxBranch tvs eta_tvs cvs lhs rhs roles loc |
| 736 | 788 | |
| 737 | 789 | -- all of the following code is here to avoid mutual dependencies with
|
| 738 | 790 | -- Coercion
|
| 739 | -mkBranchedCoAxiom :: Name -> TyCon -> [CoAxBranch] -> CoAxiom Branched
|
|
| 740 | -mkBranchedCoAxiom ax_name fam_tc branches
|
|
| 791 | +mkBranchedCoAxiom :: Role -> Name -> TyCon -> [CoAxBranch] -> CoAxiom Branched
|
|
| 792 | +mkBranchedCoAxiom role ax_name fam_tc branches
|
|
| 741 | 793 | = CoAxiom { co_ax_unique = nameUnique ax_name
|
| 742 | 794 | , co_ax_name = ax_name
|
| 743 | 795 | , co_ax_tc = fam_tc
|
| 744 | - , co_ax_role = Nominal
|
|
| 796 | + , co_ax_role = role
|
|
| 745 | 797 | , co_ax_implicit = False
|
| 746 | 798 | , co_ax_branches = manyBranches (computeAxiomIncomps branches) }
|
| 799 | + -- computeAxiomIncomps: see (SC1) in
|
|
| 800 | + -- Note [Storing compatibility]
|
|
| 747 | 801 | |
| 748 | 802 | mkUnbranchedCoAxiom :: Name -> TyCon -> CoAxBranch -> CoAxiom Unbranched
|
| 749 | 803 | mkUnbranchedCoAxiom ax_name fam_tc branch
|
| ... | ... | @@ -752,7 +806,9 @@ mkUnbranchedCoAxiom ax_name fam_tc branch |
| 752 | 806 | , co_ax_tc = fam_tc
|
| 753 | 807 | , co_ax_role = Nominal
|
| 754 | 808 | , co_ax_implicit = False
|
| 755 | - , co_ax_branches = unbranched (branch { cab_incomps = [] }) }
|
|
| 809 | + , co_ax_branches = unbranched (noAxiomIncomps branch) }
|
|
| 810 | + -- noAxiomIncomps: see (SC1) in
|
|
| 811 | + -- Note [Storing compatibility]
|
|
| 756 | 812 | |
| 757 | 813 | mkSingleCoAxiom :: Role -> Name
|
| 758 | 814 | -> [TyVar] -> [TyVar] -> [CoVar]
|
| ... | ... | @@ -767,7 +823,9 @@ mkSingleCoAxiom role ax_name tvs eta_tvs cvs fam_tc lhs_tys rhs_ty |
| 767 | 823 | , co_ax_tc = fam_tc
|
| 768 | 824 | , co_ax_role = role
|
| 769 | 825 | , co_ax_implicit = False
|
| 770 | - , co_ax_branches = unbranched (branch { cab_incomps = [] }) }
|
|
| 826 | + , co_ax_branches = unbranched (noAxiomIncomps branch) }
|
|
| 827 | + -- noAxiomIncomps: see (SC1) in
|
|
| 828 | + -- Note [Storing compatibility]
|
|
| 771 | 829 | where
|
| 772 | 830 | branch = mkCoAxBranch tvs eta_tvs cvs lhs_tys rhs_ty
|
| 773 | 831 | (map (const Nominal) tvs)
|
| ... | ... | @@ -785,7 +843,9 @@ mkNewTypeCoAxiom name tycon tvs roles rhs_ty |
| 785 | 843 | , co_ax_implicit = True -- See Note [Implicit axioms] in GHC.Core.TyCon
|
| 786 | 844 | , co_ax_role = Representational
|
| 787 | 845 | , co_ax_tc = tycon
|
| 788 | - , co_ax_branches = unbranched (branch { cab_incomps = [] }) }
|
|
| 846 | + , co_ax_branches = unbranched (noAxiomIncomps branch) }
|
|
| 847 | + -- noAxiomIncomps: see (SC1) in
|
|
| 848 | + -- Note [Storing compatibility]
|
|
| 789 | 849 | where
|
| 790 | 850 | branch = mkCoAxBranch tvs [] [] (mkTyVarTys tvs) rhs_ty
|
| 791 | 851 | roles (getSrcSpan name)
|
| ... | ... | @@ -1223,7 +1283,9 @@ findBranch :: Array BranchIndex CoAxBranch |
| 1223 | 1283 | -> Maybe (BranchIndex, [Type], [Coercion])
|
| 1224 | 1284 | -- coercions relate requested types to returned axiom LHS at role N
|
| 1225 | 1285 | findBranch branches target_tys
|
| 1226 | - = foldr go Nothing (assocs branches)
|
|
| 1286 | + = -- Implements the Closed Family Matching Rule
|
|
| 1287 | + -- in Note [Compatibility]
|
|
| 1288 | + foldr go Nothing (assocs branches)
|
|
| 1227 | 1289 | where
|
| 1228 | 1290 | go :: (BranchIndex, CoAxBranch)
|
| 1229 | 1291 | -> Maybe (BranchIndex, [Type], [Coercion])
|
| ... | ... | @@ -1258,6 +1320,20 @@ apartnessCheck target (CoAxBranch { cab_incomps = incomps }) |
| 1258 | 1320 | isSurelyApart SurelyApart = True
|
| 1259 | 1321 | isSurelyApart _ = False
|
| 1260 | 1322 | |
| 1323 | +-- | Check whether an earlier branch matches these target types
|
|
| 1324 | +noEarlierMatchCheck
|
|
| 1325 | + :: [Type]
|
|
| 1326 | + -> CoAxBranch -- ^ The candidate equation we wish to use
|
|
| 1327 | + -> Bool -- ^ True <=> equation can fire
|
|
| 1328 | +noEarlierMatchCheck target (CoAxBranch { cab_overlaps = overlaps })
|
|
| 1329 | + -- NB: this is the /only/ use of the `cab_overlaps` field
|
|
| 1330 | + -- See Note [Storing compatibility] and
|
|
| 1331 | + -- (RW4) in Note [Relevance]
|
|
| 1332 | + = not (any matches overlaps)
|
|
| 1333 | + where
|
|
| 1334 | + matches earlier_branch
|
|
| 1335 | + = isJust (tcMatchTys (coAxBranchLHS earlier_branch) target)
|
|
| 1336 | + |
|
| 1261 | 1337 | {-
|
| 1262 | 1338 | ************************************************************************
|
| 1263 | 1339 | * *
|
| ... | ... | @@ -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 or 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) $
|
| ... | ... | @@ -112,7 +112,7 @@ coAxBranchToIfaceBranch tc lhs_s |
| 112 | 112 | , ifaxbRoles = roles
|
| 113 | 113 | , ifaxbRHS = toIfaceType rhs
|
| 114 | 114 | , ifaxbIncomps = iface_incomps }
|
| 115 | - where
|
|
| 115 | + where
|
|
| 116 | 116 | iface_incomps = map (expectJust
|
| 117 | 117 | . flip findIndex lhs_s
|
| 118 | 118 | . eqTypes
|
| ... | ... | @@ -338,7 +338,12 @@ data IfaceAxBranch = IfaceAxBranch { ifaxbTyVars :: [IfaceTvBndr] |
| 338 | 338 | , ifaxbRoles :: [Role]
|
| 339 | 339 | , ifaxbRHS :: IfaceType
|
| 340 | 340 | , ifaxbIncomps :: [BranchIndex] }
|
| 341 | - -- See Note [Storing compatibility] in GHC.Core.Coercion.Axiom
|
|
| 341 | + -- We store the incompatibilities in IfaceAxBranch
|
|
| 342 | + -- just for (perhaps unnecessary) display purposes:
|
|
| 343 | + -- see Note [Displaying axiom incompatibilities]
|
|
| 344 | + -- When we construct a real CoAxBranch we compute cab_incomps directly
|
|
| 345 | + -- from the equations, ignoring the ifaxbIncomps.
|
|
| 346 | + -- We could consider getting rid of ifaxbIncomps altogether.
|
|
| 342 | 347 | |
| 343 | 348 | data IfaceConDecls
|
| 344 | 349 | = IfAbstractTyCon -- c.f TyCon.AbstractTyCon
|
| ... | ... | @@ -779,14 +784,13 @@ that is what is seen by importing module with --make |
| 779 | 784 | |
| 780 | 785 | Note [Displaying axiom incompatibilities]
|
| 781 | 786 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 782 | -With -fprint-axiom-incomps we display which closed type family equations
|
|
| 783 | -are incompatible with which. This information is sometimes necessary
|
|
| 784 | -because GHC doesn't try equations in order: any equation can be used when
|
|
| 785 | -all preceding equations that are incompatible with it do not apply.
|
|
| 786 | - |
|
| 787 | -For example, the last "a && a = a" equation in Data.Type.Bool.&& is
|
|
| 788 | -actually compatible with all previous equations, and can reduce at any
|
|
| 789 | -time.
|
|
| 787 | +With -fprint-axiom-incomps we display which closed type family equations are
|
|
| 788 | +incompatible with which (see #15546). This information is sometimes necessary
|
|
| 789 | +because GHC doesn't try equations in order: any equation can be used when all
|
|
| 790 | +preceding equations that are incompatible with it do not apply.
|
|
| 791 | + |
|
| 792 | +For example, the last "a && a = a" equation in Data.Type.Bool.&& is actually
|
|
| 793 | +compatible with all previous equations, and can reduce at any time.
|
|
| 790 | 794 | |
| 791 | 795 | This is displayed as:
|
| 792 | 796 | Prelude> :i Data.Type.Equality.==
|
| ... | ... | @@ -91,7 +91,6 @@ import GHC.Utils.Logger |
| 91 | 91 | import GHC.Data.Bag
|
| 92 | 92 | import GHC.Data.Maybe
|
| 93 | 93 | import GHC.Data.FastString
|
| 94 | -import GHC.Data.List.SetOps
|
|
| 95 | 94 | |
| 96 | 95 | import GHC.Types.Annotations
|
| 97 | 96 | import GHC.Types.SourceFile
|
| ... | ... | @@ -903,12 +902,7 @@ tc_iface_decl _ _ (IfaceAxiom { ifName = tc_name, ifTyCon = tc |
| 903 | 902 | -- See #13803
|
| 904 | 903 | ; tc_branches <- forkM (text "Axiom branches" <+> ppr tc_name)
|
| 905 | 904 | $ tc_ax_branches branches
|
| 906 | - ; let axiom = CoAxiom { co_ax_unique = nameUnique tc_name
|
|
| 907 | - , co_ax_name = tc_name
|
|
| 908 | - , co_ax_tc = tc_tycon
|
|
| 909 | - , co_ax_role = role
|
|
| 910 | - , co_ax_branches = manyBranches tc_branches
|
|
| 911 | - , co_ax_implicit = False }
|
|
| 905 | + ; let axiom = mkBranchedCoAxiom role tc_name tc_tycon tc_branches
|
|
| 912 | 906 | ; return (ACoAxiom axiom) }
|
| 913 | 907 | |
| 914 | 908 | tc_iface_decl _ _ (IfacePatSyn{ ifName = name
|
| ... | ... | @@ -1116,15 +1110,14 @@ tc_fd (tvs1, tvs2) = do { tvs1' <- mapM tcIfaceTyVar tvs1 |
| 1116 | 1110 | ; return (tvs1', tvs2') }
|
| 1117 | 1111 | |
| 1118 | 1112 | tc_ax_branches :: [IfaceAxBranch] -> IfL [CoAxBranch]
|
| 1119 | -tc_ax_branches if_branches = foldlM tc_ax_branch [] if_branches
|
|
| 1113 | +tc_ax_branches if_branches = mapM tc_ax_branch if_branches
|
|
| 1120 | 1114 | |
| 1121 | -tc_ax_branch :: [CoAxBranch] -> IfaceAxBranch -> IfL [CoAxBranch]
|
|
| 1122 | -tc_ax_branch prev_branches
|
|
| 1123 | - (IfaceAxBranch { ifaxbTyVars = tv_bndrs
|
|
| 1115 | +tc_ax_branch :: IfaceAxBranch -> IfL CoAxBranch
|
|
| 1116 | +tc_ax_branch (IfaceAxBranch { ifaxbTyVars = tv_bndrs
|
|
| 1124 | 1117 | , ifaxbEtaTyVars = eta_tv_bndrs
|
| 1125 | 1118 | , ifaxbCoVars = cv_bndrs
|
| 1126 | 1119 | , ifaxbLHS = lhs, ifaxbRHS = rhs
|
| 1127 | - , ifaxbRoles = roles, ifaxbIncomps = incomps })
|
|
| 1120 | + , ifaxbRoles = roles })
|
|
| 1128 | 1121 | = bindIfaceTyConBinders_AT
|
| 1129 | 1122 | (map (\b -> Bndr (IfaceTvBndr b) (NamedTCB Inferred)) tv_bndrs) $ \ tvs ->
|
| 1130 | 1123 | -- The _AT variant is needed here; see Note [CoAxBranch type variables] in GHC.Core.Coercion.Axiom
|
| ... | ... | @@ -1135,15 +1128,15 @@ tc_ax_branch prev_branches |
| 1135 | 1128 | ; this_mod <- getIfModule
|
| 1136 | 1129 | ; let loc = mkGeneralSrcSpan (fsLit "module " `appendFS`
|
| 1137 | 1130 | moduleNameFS (moduleName this_mod))
|
| 1138 | - br = CoAxBranch { cab_loc = loc
|
|
| 1139 | - , cab_tvs = binderVars tvs
|
|
| 1140 | - , cab_eta_tvs = eta_tvs
|
|
| 1141 | - , cab_cvs = cvs
|
|
| 1142 | - , cab_lhs = tc_lhs
|
|
| 1143 | - , cab_roles = roles
|
|
| 1144 | - , cab_rhs = tc_rhs
|
|
| 1145 | - , cab_incomps = map (prev_branches `getNth`) incomps }
|
|
| 1146 | - ; return (prev_branches ++ [br]) }
|
|
| 1131 | + ; return (CoAxBranch { cab_loc = loc
|
|
| 1132 | + , cab_tvs = binderVars tvs
|
|
| 1133 | + , cab_eta_tvs = eta_tvs
|
|
| 1134 | + , cab_cvs = cvs
|
|
| 1135 | + , cab_lhs = tc_lhs
|
|
| 1136 | + , cab_roles = roles
|
|
| 1137 | + , cab_rhs = tc_rhs
|
|
| 1138 | + , cab_overlaps = placeHolderOverlaps
|
|
| 1139 | + , cab_incomps = placeHolderIncomps }) }
|
|
| 1147 | 1140 | |
| 1148 | 1141 | tcIfaceDataCons :: Name -> TyCon -> IfaceConDecls -> IfL AlgTyConRhs
|
| 1149 | 1142 | tcIfaceDataCons tycon_name tycon if_cons
|
| ... | ... | @@ -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,20 +26,23 @@ 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 | -import GHC.Core.TyCo.Subst( elemSubst )
|
|
| 32 | +import GHC.Core.TyCo.Subst( elemSubst, extendTvSubstWithClone )
|
|
| 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
|
| 38 | +import GHC.Types.Var.Env( mkInScopeSet )
|
|
| 36 | 39 | |
| 37 | 40 | import GHC.Utils.Outputable
|
| 38 | 41 | import GHC.Utils.Panic
|
| 39 | 42 | |
| 40 | 43 | import Control.Monad( unless )
|
| 41 | 44 | import GHC.Data.Pair
|
| 42 | -import Data.Maybe( isNothing, isJust, mapMaybe )
|
|
| 45 | +import Data.Maybe( isJust, mapMaybe )
|
|
| 43 | 46 | |
| 44 | 47 | |
| 45 | 48 | {- Note [Overview of functional dependencies in type inference]
|
| ... | ... | @@ -109,7 +112,6 @@ Wrinkles |
| 109 | 112 | from fundeps, but that would require new evidence forms, and an extension to
|
| 110 | 113 | FC, so we don't do that right now (Dec 14).
|
| 111 | 114 | |
| 112 | - |
|
| 113 | 115 | Note [FunDep and implicit parameter reactions]
|
| 114 | 116 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 115 | 117 | Currently, our story of interacting two dictionaries (or a dictionary
|
| ... | ... | @@ -573,6 +575,7 @@ tryEqFunDeps work_item@(EqCt { eq_lhs = work_lhs |
| 573 | 575 | |
| 574 | 576 | |
| 575 | 577 | tryFamEqFunDeps :: TcSMode -> [EqCt] -> TyCon -> [TcType] -> EqCt -> SolverStage ()
|
| 578 | +-- See Note [Type inference for type families with injectivity]
|
|
| 576 | 579 | tryFamEqFunDeps mode eqs_for_me fam_tc work_args
|
| 577 | 580 | work_item@(EqCt { eq_ev = ev, eq_rhs = work_rhs })
|
| 578 | 581 | | Just ops <- builtInClosedTyFamTyCon_maybe fam_tc
|
| ... | ... | @@ -583,6 +586,7 @@ tryFamEqFunDeps mode eqs_for_me fam_tc work_args |
| 583 | 586 | ; tryFDEqns False fam_tc work_args work_item eqns
|
| 584 | 587 | |
| 585 | 588 | ; unless (hasRelevantGiven eqs_for_me work_args work_item) $
|
| 589 | + -- hasRelevantGiven: See (CF1) in Note [Exploiting closed type families]
|
|
| 586 | 590 | do { eqns <- mkTopBuiltinFamEqFDs fam_tc ops work_args work_rhs
|
| 587 | 591 | ; tryFDEqns True fam_tc work_args work_item eqns } }
|
| 588 | 592 | |
| ... | ... | @@ -599,8 +603,11 @@ tryFamEqFunDeps mode eqs_for_me fam_tc work_args |
| 599 | 603 | NotInjective -> nopStage ()
|
| 600 | 604 | Injective inj -> do { eqns <- mkLocalFamEqFDs eqs_for_me fam_tc inj work_args work_rhs
|
| 601 | 605 | ; tryFDEqns False fam_tc work_args work_item eqns }
|
| 606 | + -- NB: tryFDEqns bales out on an insoluble fundep
|
|
| 607 | + -- See (CF4) in Note [Exploiting closed type families]
|
|
| 602 | 608 | |
| 603 | 609 | ; unless (hasRelevantGiven eqs_for_me work_args work_item) $
|
| 610 | + -- hasRelevantGiven: See (CF1) in Note [Exploiting closed type families]
|
|
| 604 | 611 | do { eqns <- mkTopFamEqFDs fam_tc work_args work_item
|
| 605 | 612 | ; tryFDEqns True fam_tc work_args work_item eqns } }
|
| 606 | 613 | |
| ... | ... | @@ -638,10 +645,11 @@ tryFDEqns is_top fam_tc work_args work_item@(EqCt { eq_ev = ev, eq_rhs= rhs }) f |
| 638 | 645 | -- User-defined type families
|
| 639 | 646 | -----------------------------------------
|
| 640 | 647 | mkTopClosedFamEqFDs :: CoAxiom Branched -> [TcType] -> EqCt -> SolverStage [FunDepEqns]
|
| 648 | +-- Implements (INJFAM:Wanted/top-closed)
|
|
| 649 | +-- See Note [Exploiting closed type families]
|
|
| 641 | 650 | -- Look at the top-level axioms; we effectively infer injectivity,
|
| 642 | --- so we don't need tyConInjectivtyInfo. This works fine for closed
|
|
| 651 | +-- so we don't need tyConInjectivityInfo. This works fine for closed
|
|
| 643 | 652 | -- type families without injectivity info
|
| 644 | --- See Note [Exploiting closed type families]
|
|
| 645 | 653 | mkTopClosedFamEqFDs ax work_args (EqCt { eq_ev = ev, eq_rhs = work_rhs })
|
| 646 | 654 | | isGenerativeType work_rhs -- See (CF5) in Note [Exploiting closed type families]
|
| 647 | 655 | = Stage $
|
| ... | ... | @@ -679,39 +687,46 @@ hasRelevantGiven eqs_for_me work_args (EqCt { eq_rhs = work_rhs }) |
| 679 | 687 | relevant (EqCt { eq_ev = ev, eq_lhs = lhs, eq_rhs = rhs_ty })
|
| 680 | 688 | | isGiven ev
|
| 681 | 689 | , TyFamLHS _ lhs_tys <- lhs
|
| 682 | - = isJust (tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys))
|
|
| 690 | + = isJust (tcUnifyTysForInjectivity Unifying work_tys (rhs_ty:lhs_tys))
|
|
| 683 | 691 | | otherwise
|
| 684 | 692 | = False
|
| 685 | 693 | |
| 686 | 694 | getRelevantBranches :: CoAxiom Branched -> [TcType] -> Xi -> [FunDepEqns]
|
| 687 | 695 | -- Return the FunDepEqns that arise from each relevant branch
|
| 696 | +-- Implements Note [Relevance]
|
|
| 688 | 697 | getRelevantBranches ax work_args work_rhs
|
| 689 | - = go [] (fromBranches (coAxiomBranches ax))
|
|
| 698 | + = go (fromBranches (coAxiomBranches ax))
|
|
| 690 | 699 | where
|
| 691 | 700 | work_tys = work_rhs : work_args
|
| 692 | 701 | |
| 693 | - go _ [] = []
|
|
| 694 | - go preceding (branch:branches)
|
|
| 702 | + go [] = []
|
|
| 703 | + go (branch:branches)
|
|
| 695 | 704 | = case is_relevant branch of
|
| 696 | - Just eqn -> eqn : go (branch:preceding) branches
|
|
| 697 | - Nothing -> go (branch:preceding) branches
|
|
| 705 | + Just eqn -> eqn : go branches
|
|
| 706 | + Nothing -> go branches
|
|
| 698 | 707 | 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
|
|
| 708 | + is_relevant branch@(CoAxBranch { cab_tvs = qtvs
|
|
| 709 | + , cab_lhs = lhs_tys
|
|
| 710 | + , cab_rhs = rhs_ty })
|
|
| 711 | + | Just subst <- tcUnifyTysForInjectivity Unifying (rhs_ty:lhs_tys) work_tys
|
|
| 712 | + -- See (RW1)-(RW3) in Note [Relevance]
|
|
| 713 | + -- This is a pre-/unification/ check (not matching)
|
|
| 714 | + -- so `subst` can bind both `qtvs` and fvs(work_tys)
|
|
| 715 | + , let (subst',qtvs') = trim_qtvs subst qtvs
|
|
| 716 | + lhs_tys' = substTys subst' lhs_tys
|
|
| 717 | + rhs_ty' = substTy subst' rhs_ty
|
|
| 718 | + branch_tys' = rhs_ty' : lhs_tys'
|
|
| 719 | + , noEarlierMatchCheck lhs_tys' branch -- See (RW4) in Note [Relevance]
|
|
| 705 | 720 | = Just (FDEqns { fd_qtvs = qtvs'
|
| 706 | - , fd_eqs = zipWith Pair (rhs_ty':lhs_tys') work_tys })
|
|
| 721 | + , fd_eqs = zipWith Pair branch_tys' work_tys })
|
|
| 722 | + -- Do not apply the substition to `work_tys`;
|
|
| 723 | + -- See (CF7) in Note [Exploiting closed type families]
|
|
| 707 | 724 | | otherwise
|
| 708 | 725 | = Nothing
|
| 709 | 726 | |
| 710 | - no_match lhs_tys (CoAxBranch { cab_lhs = lhs_tys1 })
|
|
| 711 | - = isNothing (tcUnifyTysForInjectivity False lhs_tys1 lhs_tys)
|
|
| 712 | - |
|
| 713 | 727 | mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> EqCt -> TcS [FunDepEqns]
|
| 714 | --- Implements (INJFAM:Wanted/top)
|
|
| 728 | +-- Implements (INJFAM:Wanted/top-open)
|
|
| 729 | +-- See Note [Exploiting open type families]
|
|
| 715 | 730 | mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs })
|
| 716 | 731 | = do { fam_envs <- getFamInstEnvs
|
| 717 | 732 | ; let branches :: [CoAxBranch]
|
| ... | ... | @@ -720,15 +735,15 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs }) |
| 720 | 735 | ; return (mapMaybe do_one branches) }
|
| 721 | 736 | where
|
| 722 | 737 | 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
|
|
| 738 | + do_one (CoAxBranch { cab_tvs = branch_qtvs
|
|
| 739 | + , cab_lhs = branch_lhs_tys
|
|
| 740 | + , cab_rhs = branch_rhs })
|
|
| 741 | + | Just subst <- tcUnifyTysForInjectivity Matching [branch_rhs] [work_rhs]
|
|
| 742 | + , let (subst', qtvs') = trim_qtvs subst branch_qtvs
|
|
| 729 | 743 | 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)
|
|
| 744 | + -- No need for an apartness check here; for open type families
|
|
| 745 | + -- there are no "preceding" equations
|
|
| 746 | + = Just (mkInjectivityFDEqn inj_flags qtvs' branch_lhs_tys' work_args)
|
|
| 732 | 747 | |
| 733 | 748 | | otherwise
|
| 734 | 749 | = Nothing
|
| ... | ... | @@ -736,7 +751,7 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs }) |
| 736 | 751 | mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> SolverStage [FunDepEqns]
|
| 737 | 752 | -- Wanted constraints only
|
| 738 | 753 | -- Both open and closed type families, but only ones with declared injectivity
|
| 739 | --- See Note [Type inference for type families with injectivity] esp (TIF2)
|
|
| 754 | +-- See Note [Exploiting local type-family injectivity]
|
|
| 740 | 755 | mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
|
| 741 | 756 | = do { let -- eqns_from_inerts: see (INJFAM:Wanted/other)
|
| 742 | 757 | eqns_from_inerts = mapMaybe do_one eqs_for_me
|
| ... | ... | @@ -755,15 +770,27 @@ mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs |
| 755 | 770 | |
| 756 | 771 | mk_eqn iargs = mkInjectivityFDEqn inj_flags [] work_args iargs
|
| 757 | 772 | |
| 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')
|
|
| 773 | +trim_qtvs :: Subst -> [TyVar] -> (Subst, [TyVar])
|
|
| 774 | +-- Tricky stuff: see (OF1) in Note [Exploiting open type families]
|
|
| 775 | +trim_qtvs unif_subst qtvs
|
|
| 776 | + = go unif_subst qtvs
|
|
| 777 | + where
|
|
| 778 | + go :: Subst -> [TyVar] -> (Subst, [TyVar])
|
|
| 779 | + go subst [] = (subst, [])
|
|
| 780 | + go subst (tv:tvs)
|
|
| 781 | + | tv `elemSubst` unif_subst = go subst tvs
|
|
| 782 | + | otherwise = go_fresh subst tv tvs
|
|
| 783 | + |
|
| 784 | + -- Using an auxiliary function here to avoid prematurely forcing
|
|
| 785 | + -- the (banged) recursive call to `go` in the non-fresh case
|
|
| 786 | + go_fresh subst tv tvs = (subst'', tv':tvs')
|
|
| 787 | + where
|
|
| 788 | + !(subst'', tvs') = go subst' tvs
|
|
| 789 | + tv' = tv `setTyVarKind` substTy subst (tyVarKind tv)
|
|
| 790 | + subst' = extendTvSubstWithClone subst tv tv'
|
|
| 791 | + -- extendTvSubstWithClone: see (OF1b) in
|
|
| 792 | + -- Note [Exploiting open type families]
|
|
| 793 | + |
|
| 767 | 794 | |
| 768 | 795 | -----------------------------------------
|
| 769 | 796 | -- Built-in type families
|
| ... | ... | @@ -924,15 +951,20 @@ we attempt to exploit injectivity, via `mkLocalFamEqFDs`: |
| 924 | 951 | * (INJFAM:Wanted/other) see `mkLocalFamEqFDs`
|
| 925 | 952 | work item: [W] F s1 s2 ~ rhs -- Wanted
|
| 926 | 953 | inert: [G/W] F t2 t2 ~ rhs -- Same `rhs`, Given or Wanted
|
| 927 | - We can generate FunDepEqns: (s2 ~ t2)
|
|
| 954 | + See Note [Exploiting local type-family injectivity]
|
|
| 955 | + |
|
| 956 | +* (INJFAM:Wanted/top-open) for open type families: `mkTopOpenFamEqFDs`
|
|
| 957 | + type family F a b = r | r -> b
|
|
| 958 | + type instance F Int (Maybe a) = [G Int] -- G is a type family
|
|
| 959 | + [W] F alpha beta = [ty]
|
|
| 960 | + We can generate (Maybe gamma ~ beta)
|
|
| 961 | + See Note [Exploiting open type families]
|
|
| 928 | 962 | |
| 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)
|
|
| 963 | +* (INJFAM:Wanted/top-closed) for closed type families: `mkTopClosedFamEqFDs`
|
|
| 964 | + type family F a b where { ...eqns... }
|
|
| 965 | + [W] F alpha ~ Int
|
|
| 966 | + We may be able to generate some extra equalities to constraint `alpha`
|
|
| 967 | + See very clever Note [Exploiting closed type families]
|
|
| 936 | 968 | |
| 937 | 969 | For /built-in/ type families, it's pretty similar, except that
|
| 938 | 970 | |
| ... | ... | @@ -945,45 +977,36 @@ For /built-in/ type families, it's pretty similar, except that |
| 945 | 977 | * mkLocalBuiltinFamEqFDs
|
| 946 | 978 | * mkTopBuiltinFamEqFDs
|
| 947 | 979 | |
| 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))
|
|
| 954 | - |
|
| 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`.
|
|
| 964 | - |
|
| 965 | -(TIF2) All this applies equally to /closed/ type families; it is /not/
|
|
| 966 | - subsumed by Note [Exploiting closed type families]. Consider:
|
|
| 980 | +Note [Exploiting local type-family injectivity] see `mkLocalFamEqFDs`
|
|
| 981 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 982 | +Suppose we have a type family with declared injectivity:
|
|
| 983 | + type family F a b = r | r -> b
|
|
| 984 | +and we have
|
|
| 985 | + work item: [W] F s1 s2 ~ F t1 t2
|
|
| 986 | +or
|
|
| 987 | + work item: [W] F s1 s2 ~ rhs -- Wanted
|
|
| 988 | + inert: [G/W] F t2 t2 ~ rhs -- Same `rhs`, Given or Wanted
|
|
| 989 | + |
|
| 990 | +Then we can generate FunDepEqns: (s2 ~ t2)
|
|
| 991 | + |
|
| 992 | +This applies equally to /closed/ type families; it is /not/ subsumed
|
|
| 993 | +by Note [Exploiting closed type families]. Consider:
|
|
| 994 | + |
|
| 967 | 995 | type family F a | r -> a where { .... }
|
| 968 | 996 | |
| 969 | 997 | [W] F t1 ~ a
|
| 970 | 998 | [W] F t2 ~ a
|
| 971 | 999 | |
| 972 | - Then since F is declared injective, we can generate t1~t2.
|
|
| 1000 | +Then since F is declared injective, we can generate t1~t2.
|
|
| 973 | 1001 | |
| 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].)
|
|
| 1002 | +As for open type families, we insist on /user-declared/ injectivity only; we
|
|
| 1003 | +don't try to /infer/ injectivity even for a closed family. See Section 3.4
|
|
| 1004 | +of the "Injective type families" paper. (Arguably, we could /infer/
|
|
| 1005 | +injectivity for closed type families, and that would be more in the spirit of
|
|
| 1006 | +Note [Exploiting closed type families].)
|
|
| 979 | 1007 | |
| 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 | -~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1008 | +Note [Relevance]
|
|
| 1009 | +~~~~~~~~~~~~~~~~
|
|
| 987 | 1010 | We say that a closed-type-family equation `F lhs = rhs` is
|
| 988 | 1011 | /relevant/ for a Wanted [W] F wlhs ~ wrhs
|
| 989 | 1012 | iff
|
| ... | ... | @@ -992,6 +1015,10 @@ iff |
| 992 | 1015 | |
| 993 | 1016 | (R2) There is no earlier equation that matches S(lhs). See (RW4) below.
|
| 994 | 1017 | |
| 1018 | +The relevance check is implemented by `getRelevantBranches`, which actually
|
|
| 1019 | +returns the [FunDepEqns] described in the Closed Family Fundep Algorithm in
|
|
| 1020 | +Note [Exploiting closed type families].
|
|
| 1021 | + |
|
| 995 | 1022 | (RW1) Pre-unification treats type-family applications as binding to anything,
|
| 996 | 1023 | rather like type variables. If two types don't even pre-unify, we say that they
|
| 997 | 1024 | are /apart/. It is done by `tcUnifyTysForInjectivity`.
|
| ... | ... | @@ -1014,24 +1041,130 @@ iff |
| 1014 | 1041 | Clearly the RHS is apart from the first equation and we want to fire injectivity
|
| 1015 | 1042 | on the second equation.
|
| 1016 | 1043 | |
| 1017 | -(RW4) Why "no earlier equation matches" in conditoin (R2)? Consider the family
|
|
| 1044 | +(RW4) Why "no earlier equation matches" in condition (R2)? Consider the family
|
|
| 1018 | 1045 | |
| 1019 | 1046 | type family Bak a = r where
|
| 1020 | 1047 | Bak Int = Char -- B1
|
| 1021 | 1048 | Bak Char = Int -- B2
|
| 1022 | 1049 | Bak a = a -- B3
|
| 1023 | 1050 | |
| 1024 | - and [W] Bak alpha ~ Char. In fact, only (B2) is relevant for this Wanted.
|
|
| 1051 | + and [W] Bak alpha ~ Char. In fact, only (B1) is relevant for this Wanted.
|
|
| 1025 | 1052 | You might think that (B3) could be instantiated to Bak Char ~ Char; but
|
| 1026 | 1053 | 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
|
|
| 1028 | - can emit [W] alpha ~ Int. Hence (B3) is not relevant; only (B2) is relevant.
|
|
| 1054 | + fire first. So the only way to return a Char is via (B1); so we
|
|
| 1055 | + can emit [W] alpha ~ Int. Hence (B3) is not relevant; only (B1) is relevant.
|
|
| 1029 | 1056 | |
| 1030 | 1057 | That is the reason for condition (R2) in the definition of Relevance above.
|
| 1031 | 1058 | A watertight proof that this is the Right Thing is not very easy. See more
|
| 1032 | - discussion in #23162.
|
|
| 1033 | - |
|
| 1034 | -Note [Exploiting closed type families]
|
|
| 1059 | + discussion in #23162, and Section 5.2 of the paper.
|
|
| 1060 | + |
|
| 1061 | + How, precisely, do we implement (R2)? We check that there is no earlier equation
|
|
| 1062 | + that fires on S(lhs), in this case (on Bak Char). Notice that this is different
|
|
| 1063 | + from the `apartnessCheck`, which checks that all preceding equations are apart
|
|
| 1064 | + from S(lhs). Apartness checking uses /unification/; here we want /matching/.
|
|
| 1065 | + Hence using `noEarlierMatchCheck`, not `apartnessCheck`.
|
|
| 1066 | + |
|
| 1067 | + Here's a good example from T27171_aux. T
|
|
| 1068 | + type family TMessage m where
|
|
| 1069 | + {- T1 -} TMessage @f @t (CustomMethod s :: Method f t) = ()
|
|
| 1070 | + {- T2 -} TMessage @f @Req (m :: Method f Req) = TRequestMessage m
|
|
| 1071 | + {- T3 -} TMessage @f @Not (m :: Method f Not) = TNotificationMessage m
|
|
| 1072 | + |
|
| 1073 | + [W] TMessage @SC @Req alpha ~# TRequestMessage alpha
|
|
| 1074 | + |
|
| 1075 | + There is only one relevant equation, namely (T2). If we apply its
|
|
| 1076 | + pre-unification substitution [f :-> SC, m :-> alpha] to its LHS we get
|
|
| 1077 | + TMessage @SC @Req alpha
|
|
| 1078 | + and equation (T1) does not match that. (It does unify, but we don't care.)
|
|
| 1079 | + |
|
| 1080 | +(RW5) `noEarlierMatchCheck`: in (RW4) We really do need to check that /no/
|
|
| 1081 | + earlier equation matches, not just no earlier /incompatible/ equation
|
|
| 1082 | + matches. Consider T27828a:
|
|
| 1083 | + type family F a where
|
|
| 1084 | + F Int = Int -- B1
|
|
| 1085 | + F Char = Bool -- B2
|
|
| 1086 | + F a = a -- B3
|
|
| 1087 | + |
|
| 1088 | + [W] F alpha ~ Int
|
|
| 1089 | + |
|
| 1090 | + (B1) is relevant, and (B2) is not. What about (B3)? It pre-unifies with
|
|
| 1091 | + the Wanted via [alpha :-> Int, a :-> Int]. But under that substitution
|
|
| 1092 | + (B1) would fire, so (B3) is not relevant.
|
|
| 1093 | + |
|
| 1094 | + And yet, (B1) is /compatible/ with (B3), so it's no good just looking at
|
|
| 1095 | + the `cab_incomps` of (B3). Instead we look at `cab_overlaps`.
|
|
| 1096 | + |
|
| 1097 | +Note [Exploiting open type families] see `mkTopOpenFamEqFDs`
|
|
| 1098 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1099 | +Generating fundeps from a top-level type instance is covered in Section 5.2 in
|
|
| 1100 | +the Injective Type Families paper. For open type families, suppose we have
|
|
| 1101 | + |
|
| 1102 | + type family F a = r | r -> a
|
|
| 1103 | + type instance F [a] = a->a
|
|
| 1104 | + |
|
| 1105 | + [W] F alpha ~ Int->Int
|
|
| 1106 | + |
|
| 1107 | +Then, since F has been checked as injective, and the RHS `a->a` (pre-)unifies
|
|
| 1108 | +with the `Int->Int` in the Wanted with substitution [a :-> Int], we can
|
|
| 1109 | +add a derived FunDepEqns
|
|
| 1110 | + FDEqns{ fd_qtvs = [], fd_eqs = [ [Int] ~ alpha ] }
|
|
| 1111 | +and thereby emit (via `instantiateFunDepEqns`)
|
|
| 1112 | + [W] [Int] ~ alpha
|
|
| 1113 | + |
|
| 1114 | +Things are a bit trickier when not all the quantified variables of the
|
|
| 1115 | +instance are bound by the pre-unification step. Suppose we have
|
|
| 1116 | + |
|
| 1117 | + type family F a = r | r -> a
|
|
| 1118 | + type instance F (Maybe a) = [G a] -- G is a type family
|
|
| 1119 | + |
|
| 1120 | + [W] F alpha ~ [ty]
|
|
| 1121 | + |
|
| 1122 | +Then, the RHS [G a] pre-unifies with the RHS of the Wanted, but with an
|
|
| 1123 | +empty substitution, which does not fix `a`. So we get this FunDepEqns:
|
|
| 1124 | + FDEqns{ fd_qtvs = a, fd_eqs = [ Maybe a ~ alpha ] }
|
|
| 1125 | +(note the fd_qtvs=a) and thereby emit (via `instantiateFunDepEqns`)
|
|
| 1126 | + [W] Maybe gamma ~ alpha -- Fresh gamma
|
|
| 1127 | +We have learned that `alpha` must be a list, but that is all; we don't
|
|
| 1128 | +know what is inside it, hence the fresh `gamma`.
|
|
| 1129 | + |
|
| 1130 | +In general we have:
|
|
| 1131 | + |
|
| 1132 | + type family F x1 ... xn = r | r -> x1 x3 (say)
|
|
| 1133 | + type instance forall qs. F t1 ... tn = rhs
|
|
| 1134 | + [W] F a1 ... an ~ b
|
|
| 1135 | + |
|
| 1136 | +Suppose `b` pre-unifies with `rhs`, with substitution `S` that binds
|
|
| 1137 | +some (but perhaps not all) of the `qs`. Lets say
|
|
| 1138 | + unbound_qs = qs \ dom(S)
|
|
| 1139 | + |
|
| 1140 | +Then we generate the FunDepEqs
|
|
| 1141 | + FDEqns{ fd_qtvs = unbound_qs
|
|
| 1142 | + , fd_eqs = [ S(t1) ~ S(a1), S(t3) ~ S(a3) ]
|
|
| 1143 | + |
|
| 1144 | +These 'fd_qtvs' are subsequently instantiated to fresh metavariables by
|
|
| 1145 | +'instantiateFunDepEqns'.
|
|
| 1146 | + |
|
| 1147 | +(OF1) The computation of `unbound_qs` is done by `trim_qtvs`, but we
|
|
| 1148 | + have to be careful. Suppose (OF1a)
|
|
| 1149 | + qs = [ k::*, a::k ]
|
|
| 1150 | + S = [ k :-> UnliftedType ]
|
|
| 1151 | + Then we want
|
|
| 1152 | + unbound_qs = [ a::UnliftedType ] -- Must apply S to q's kind!!
|
|
| 1153 | + |
|
| 1154 | + And (OF1b), although I'm not sure if this can acutally happen:
|
|
| 1155 | + qs = [ k::*, a::(k::*), b::(a::k) ]
|
|
| 1156 | + S = [ k :-> UnliftedType ]
|
|
| 1157 | + We want
|
|
| 1158 | + unbound_qs = [ a::UnliftedType, b::(a::UnliftedType) ]
|
|
| 1159 | + Note that the occurrence of `a` in b's kind should be replaced by the
|
|
| 1160 | + newly-kinded `a` not the original `a::k`.
|
|
| 1161 | + |
|
| 1162 | + This fancy footwork for `fd_qtvs` is done by `trim_qtvs`. It
|
|
| 1163 | + * Drops a quantified tyvar that /is/ matched
|
|
| 1164 | + * Substitutes in the kind of a quantified tyvar `a` that is /not/ matched
|
|
| 1165 | + * Adds the substitution [a::k :-> a::S(k)] to the substitution
|
|
| 1166 | + |
|
| 1167 | +Note [Exploiting closed type families] see `mkTopClosedFamEqFDs`
|
|
| 1035 | 1168 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1036 | 1169 | Suppose we have
|
| 1037 | 1170 | type family F a b where
|
| ... | ... | @@ -1042,17 +1175,18 @@ Suppose we have |
| 1042 | 1175 | [W] F Int alpha ~ Char
|
| 1043 | 1176 | |
| 1044 | 1177 | 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
|
|
| 1178 | +alpha:=Char without risking losing any solutions. We don't even need any
|
|
| 1179 | +injectivity annotations. Ticket #23162 has lots of background detail.
|
|
| 1047 | 1180 | |
| 1048 | -More precisely, here is the Closed Family Fundep Algorithm (CFFA)
|
|
| 1181 | +More precisely, here is the very clever Closed Family Fundep Algorithm (CFFA)
|
|
| 1049 | 1182 | |
| 1050 | 1183 | IF * F a is a closed type family.
|
| 1051 | 1184 | * 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
|
|
| 1185 | + * There are no "relevant Givens" [G] F lhs ~ rhs. See (CF1) below.
|
|
| 1186 | + * F has exactly one equation, F lhs = rhs that is "relevant" for
|
|
| 1187 | + that Wanted (see Note [Relevance])
|
|
| 1054 | 1188 | THEN
|
| 1055 | - we can emit and solve the fundep equalities:
|
|
| 1189 | + we can emit and solve the fundeps :: [FunDepEqns]:
|
|
| 1056 | 1190 | [W] wlhs1 ~ lhs1
|
| 1057 | 1191 | ...
|
| 1058 | 1192 | [W] wlhsn ~ lhsn
|
| ... | ... | @@ -1060,7 +1194,10 @@ More precisely, here is the Closed Family Fundep Algorithm (CFFA) |
| 1060 | 1194 | with fresh unification vars in lhs and rhs for the quantified variables of the
|
| 1061 | 1195 | equation.
|
| 1062 | 1196 | |
| 1063 | -See Definition [Relevance] for what "relevant" means.
|
|
| 1197 | + Actually we take advantage of the substitution generated by the relevance
|
|
| 1198 | + check, see (CF7) below.
|
|
| 1199 | + |
|
| 1200 | +See Note [Relevance] for what "relevant" means.
|
|
| 1064 | 1201 | We need to take care about non-termination; see (CF3).
|
| 1065 | 1202 | |
| 1066 | 1203 | Key point: equations that are not relevant do not need to be considered for fundeps at all.
|
| ... | ... | @@ -1166,6 +1303,8 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1166 | 1303 | I was looking at non-termination for closed type families, but it's a small
|
| 1167 | 1304 | improvement in general.
|
| 1168 | 1305 | |
| 1306 | + This bale-out is implementedn in `tryFDEqns`.
|
|
| 1307 | + |
|
| 1169 | 1308 | (CF5) Consider (see "Yikes5" in #23162):
|
| 1170 | 1309 | type family F a where
|
| 1171 | 1310 | F (Just x) = Int
|
| ... | ... | @@ -1196,7 +1335,7 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1196 | 1335 | type family I t = res | res -> t where
|
| 1197 | 1336 | I TInt = Int |> g -- where g :: Type ~# IK k
|
| 1198 | 1337 | and [W] I alpha ~ Int |> g2
|
| 1199 | - Here we definiteily want to take advantage of injectivity.
|
|
| 1338 | + Here we definitely want to take advantage of injectivity.
|
|
| 1200 | 1339 | |
| 1201 | 1340 | (CF6) This machinery can also have a significant positive effect on the size of
|
| 1202 | 1341 | proof terms. For example (simplification of T26426):
|
| ... | ... | @@ -1204,7 +1343,8 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1204 | 1343 | type family (++) a b where { '[] ++ ys = ys; (x:xs) ++ ys = x : (xs ++ ys) }
|
| 1205 | 1344 | type family MapId a where { MapId '[] = '[]; MapId (x:xs) = x : MapId xs }
|
| 1206 | 1345 | |
| 1207 | - app :: (MapId xs ++ MapId ys ~ MapId (xs ++ ys)) => Proxy xs -> Proxy ys -> Proxy (xs ++ ys)
|
|
| 1346 | + app :: (MapId xs ++ MapId ys ~ MapId (xs ++ ys))
|
|
| 1347 | + => Proxy xs -> Proxy ys -> Proxy (xs ++ ys)
|
|
| 1208 | 1348 | |
| 1209 | 1349 | test :: Proxy [ty_1, ..., ty_n]
|
| 1210 | 1350 | test = Proxy @'[ty_1]
|
| ... | ... | @@ -1248,6 +1388,30 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1248 | 1388 | instead of relying on recursively built sub-proof terms, which brings down
|
| 1249 | 1389 | coercion sizes (in certain situations) from O(n^3) to O(n^2).
|
| 1250 | 1390 | |
| 1391 | +(CF7) Relevance. When computing relevance in the Closed Family Fundep Algorithm,
|
|
| 1392 | + for [W] F wlhs1 wlhs2 ~ wrhs, against an equation F lhs1 lhs2 ~ rhs
|
|
| 1393 | + we get back a pre-unifying substitution S that makes the two as equal as poss.
|
|
| 1394 | + Then we use `trim_qtvs` in exactly the same way as in
|
|
| 1395 | + (OF1) of Note [Exploiting open type families], to generate qtvs' and S'
|
|
| 1396 | + Then we generate
|
|
| 1397 | + FDEqns { fd_qtvs = qtvs', fd_eqs [ S'(lhs1) ~ wlhs1
|
|
| 1398 | + , S'(lhs2) ~ wlhs2
|
|
| 1399 | + , S'(rhs) ~ wrhs ] }
|
|
| 1400 | + Notice that we do /not/ apply S' to wlhs/wrhs. These type contain unification
|
|
| 1401 | + variables that we must actually unify! Example
|
|
| 1402 | + type family F a b where
|
|
| 1403 | + F [a] (Maybe b) = (a, G b)
|
|
| 1404 | + [W] F alpha beta ~ (Int, [gamma])
|
|
| 1405 | + Pre-unification gives [alpha :-> [a], beta :-> Maybe b, a :-> Int]
|
|
| 1406 | + This substitution eliminates the quantified variable `a` but not `b`, so we
|
|
| 1407 | + want this:
|
|
| 1408 | + FDEqns { fd_qtvs = [b], fd_eqs [ [Int] ~ alpha
|
|
| 1409 | + , Maybe b ~ beta
|
|
| 1410 | + , (Int,G b) ~ (Int, [gamma]) ] }
|
|
| 1411 | + |
|
| 1412 | + Notice also that by applying the substitution to the template but not to the
|
|
| 1413 | + Wanted, we uphold the `fd_eqs` invariant in `FDEqns` (see its data type decl)
|
|
| 1414 | + |
|
| 1251 | 1415 | Note [Cache-caused loops]
|
| 1252 | 1416 | ~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1253 | 1417 | It is very dangerous to cache a rewritten wanted family equation as 'solved' in
|
| ... | ... | @@ -1340,28 +1504,34 @@ solveFunDeps work_ev fd_eqns |
| 1340 | 1504 | ; uPairsTcM uenv eqs }
|
| 1341 | 1505 | |
| 1342 | 1506 | instantiateFunDepEqns :: FunDepEqns -> TcM [TypeEqn]
|
| 1343 | -instantiateFunDepEqns (FDEqns { fd_qtvs = tvs, fd_eqs = eqs })
|
|
| 1344 | - | null tvs
|
|
| 1507 | +-- See GHC.Tc.Instance.Fundeps Note [Improving against instances]
|
|
| 1508 | +-- Wrinkle (IMP1)
|
|
| 1509 | +instantiateFunDepEqns (FDEqns { fd_qtvs = qtvs, fd_eqs = eqs })
|
|
| 1510 | + | null qtvs
|
|
| 1345 | 1511 | = return rev_eqs
|
| 1346 | 1512 | | otherwise
|
| 1347 | - = do { TcM.traceTc "instantiateFunDepEqns" (ppr tvs $$ ppr eqs)
|
|
| 1348 | - ; (_, subst) <- instFlexiXTcM emptySubst tvs -- Takes account of kind substitution
|
|
| 1513 | + = do { TcM.traceTc "instantiateFunDepEqns" (ppr qtvs $$ ppr eqs)
|
|
| 1514 | + ; (_, subst) <- instFlexiXTcM empty_subst qtvs -- Takes account of kind substitution
|
|
| 1349 | 1515 | ; return (map (subst_pair subst) rev_eqs) }
|
| 1350 | 1516 | where
|
| 1351 | 1517 | rev_eqs = reverse eqs
|
| 1352 | 1518 | -- (reverse eqs): See Note [Reverse order of fundep equations]
|
| 1353 | 1519 | |
| 1520 | + -- The kinds of `qtvs` can have free variables, because of `trim_qtvs`
|
|
| 1521 | + -- Example: T27828b
|
|
| 1522 | + empty_subst = mkEmptySubst $ mkInScopeSet $
|
|
| 1523 | + tyCoVarsOfTypes (map tyVarKind qtvs)
|
|
| 1524 | + |
|
| 1354 | 1525 | subst_pair subst (Pair ty1 ty2)
|
| 1355 | - = Pair (substTyUnchecked subst' ty1) ty2
|
|
| 1356 | - -- ty2 does not mention fd_qtvs, so no need to subst it.
|
|
| 1357 | - -- See GHC.Tc.Instance.Fundeps Note [Improving against instances]
|
|
| 1358 | - -- Wrinkle (1)
|
|
| 1526 | + = Pair (substTy subst' ty1) ty2
|
|
| 1527 | + -- NB: ty2 does not mention fd_qtvs, so no need to subst it.
|
|
| 1528 | + -- See invariant on `fv_eqs` in `data FunDepEqns`.
|
|
| 1359 | 1529 | where
|
| 1360 | 1530 | subst' = extendSubstInScopeSet subst (tyCoVarsOfType ty1)
|
| 1361 | 1531 | -- The free vars of ty1 aren't just fd_qtvs: ty1 is the result
|
| 1362 | 1532 | -- of matching with the [W] constraint. So we add its free
|
| 1363 | 1533 | -- vars to InScopeSet, to satisfy substTy's invariants, even
|
| 1364 | - -- though ty1 will never (currently) be a poytype, so this
|
|
| 1534 | + -- though ty1 will never (currently) be a polytype, so this
|
|
| 1365 | 1535 | -- InScopeSet will never be looked at.
|
| 1366 | 1536 | |
| 1367 | 1537 |
| ... | ... | @@ -3462,7 +3462,7 @@ tcFamDecl1 parent (FamilyDecl { fdInfo = fam_info |
| 3462 | 3462 | |
| 3463 | 3463 | ; let mb_co_ax
|
| 3464 | 3464 | | null eqns = Nothing -- mkBranchedCoAxiom fails on empty list
|
| 3465 | - | otherwise = Just (mkBranchedCoAxiom co_ax_name fam_tc branches)
|
|
| 3465 | + | otherwise = Just (mkBranchedCoAxiom Nominal co_ax_name fam_tc branches)
|
|
| 3466 | 3466 | |
| 3467 | 3467 | fam_tc = mkFamilyTyCon tc_name kind tc_bndrs 0 res_kind (resultVariableName sig)
|
| 3468 | 3468 | (ClosedTypeFamilyTyCon $ CTF mb_co_ax) parent inj'
|
| 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)) |
| 1 | +{-# LANGUAGE TypeFamilies #-}
|
|
| 2 | + |
|
| 3 | +module T27828a where
|
|
| 4 | + |
|
| 5 | +import Data.Proxy
|
|
| 6 | + |
|
| 7 | +type family F a where
|
|
| 8 | + F Int = Int -- B1
|
|
| 9 | + F Char = Bool -- B2
|
|
| 10 | + F a = a -- B3
|
|
| 11 | + |
|
| 12 | +h :: (F a ~ Int) => Proxy a -> ()
|
|
| 13 | +h = error "urk"
|
|
| 14 | + |
|
| 15 | +k :: ()
|
|
| 16 | +k = h Proxy -- [W] F alpha ~ Int |
| 1 | +{-# LANGUAGE TypeFamilies, KindSignatures, AllowAmbiguousTypes #-}
|
|
| 2 | + |
|
| 3 | +module T27828b where
|
|
| 4 | + |
|
| 5 | +type family IsJust (m :: Maybe k) :: Bool where
|
|
| 6 | + IsJust ('Just x) = 'True
|
|
| 7 | + IsJust 'Nothing = 'False
|
|
| 8 | + |
|
| 9 | +f :: forall k (m :: Maybe k). (IsJust m ~ 'True) => Int -> Int
|
|
| 10 | +f = error "urk"
|
|
| 11 | + |
|
| 12 | +g _ = f 3 -- Triggered checkValidSubst error in `instantiateFunDepEqns`o |
| ... | ... | @@ -316,3 +316,6 @@ 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, [''])
|
|
| 320 | +test('T27828a', normal, compile, [''])
|
|
| 321 | +test('T27828b', normal, compile, ['']) |