Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
ba210d98
by Simon Peyton Jones at 2025-09-08T16:26:36+01:00
15 changed files:
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Utils/TcType.hs
- testsuite/tests/typecheck/should_fail/T18851.hs
- + testsuite/tests/typecheck/should_fail/T26255a.hs
- + testsuite/tests/typecheck/should_fail/T26255a.stderr
- + testsuite/tests/typecheck/should_fail/T26255b.hs
- + testsuite/tests/typecheck/should_fail/T26255b.stderr
- + testsuite/tests/typecheck/should_fail/T26255c.hs
- + testsuite/tests/typecheck/should_fail/T26255c.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
- testsuite/tests/typecheck/should_fail/all.T
Changes:
| ... | ... | @@ -132,7 +132,7 @@ module GHC.Core.Type ( |
| 132 | 132 | kindBoxedRepLevity_maybe,
|
| 133 | 133 | mightBeLiftedType, mightBeUnliftedType,
|
| 134 | 134 | definitelyLiftedType, definitelyUnliftedType,
|
| 135 | - isAlgType, isDataFamilyAppType,
|
|
| 135 | + isAlgType, isDataFamilyApp, isSatTyFamApp,
|
|
| 136 | 136 | isPrimitiveType, isStrictType, isTerminatingType,
|
| 137 | 137 | isLevityTy, isLevityVar,
|
| 138 | 138 | isRuntimeRepTy, isRuntimeRepVar, isRuntimeRepKindedTy,
|
| ... | ... | @@ -2292,6 +2292,21 @@ isFamFreeTy (ForAllTy _ ty) = isFamFreeTy ty |
| 2292 | 2292 | isFamFreeTy (CastTy ty _) = isFamFreeTy ty
|
| 2293 | 2293 | isFamFreeTy (CoercionTy _) = False -- Not sure about this
|
| 2294 | 2294 | |
| 2295 | +-- | Check whether a type is a data family type
|
|
| 2296 | +isDataFamilyApp :: Type -> Bool
|
|
| 2297 | +isDataFamilyApp ty = case tyConAppTyCon_maybe ty of
|
|
| 2298 | + Just tc -> isDataFamilyTyCon tc
|
|
| 2299 | + _ -> False
|
|
| 2300 | + |
|
| 2301 | +isSatTyFamApp :: Type -> Maybe (TyCon, [Type])
|
|
| 2302 | +-- Return the argument if we have a saturated type family application
|
|
| 2303 | +-- Why saturated? See (ATF4) in Note [Apartness and type families]
|
|
| 2304 | +isSatTyFamApp (TyConApp tc tys)
|
|
| 2305 | + | isTypeFamilyTyCon tc
|
|
| 2306 | + && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated
|
|
| 2307 | + = Just (tc, tys)
|
|
| 2308 | +isSatTyFamApp _ = Nothing
|
|
| 2309 | + |
|
| 2295 | 2310 | buildSynTyCon :: Name -> [KnotTied TyConBinder] -> Kind -- ^ /result/ kind
|
| 2296 | 2311 | -> [Role] -> KnotTied Type -> TyCon
|
| 2297 | 2312 | -- This function is here because here is where we have
|
| ... | ... | @@ -2459,12 +2474,6 @@ isAlgType ty |
| 2459 | 2474 | isAlgTyCon tc
|
| 2460 | 2475 | _other -> False
|
| 2461 | 2476 | |
| 2462 | --- | Check whether a type is a data family type
|
|
| 2463 | -isDataFamilyAppType :: Type -> Bool
|
|
| 2464 | -isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of
|
|
| 2465 | - Just tc -> isDataFamilyTyCon tc
|
|
| 2466 | - _ -> False
|
|
| 2467 | - |
|
| 2468 | 2477 | -- | Computes whether an argument (or let right hand side) should
|
| 2469 | 2478 | -- be computed strictly or lazily, based only on its type.
|
| 2470 | 2479 | -- Currently, it's just 'isUnliftedType'.
|
| ... | ... | @@ -1741,8 +1741,8 @@ unify_ty env ty1 ty2 kco |
| 1741 | 1741 | where
|
| 1742 | 1742 | mb_tc_app1 = splitTyConApp_maybe ty1
|
| 1743 | 1743 | mb_tc_app2 = splitTyConApp_maybe ty2
|
| 1744 | - mb_sat_fam_app1 = isSatFamApp ty1
|
|
| 1745 | - mb_sat_fam_app2 = isSatFamApp ty2
|
|
| 1744 | + mb_sat_fam_app1 = isSatTyFamApp ty1
|
|
| 1745 | + mb_sat_fam_app2 = isSatTyFamApp ty2
|
|
| 1746 | 1746 | |
| 1747 | 1747 | unify_ty _ _ _ _ = surelyApart
|
| 1748 | 1748 | |
| ... | ... | @@ -1801,16 +1801,6 @@ unify_tys env orig_xs orig_ys |
| 1801 | 1801 | -- Possibly different saturations of a polykinded tycon
|
| 1802 | 1802 | -- See Note [Polykinded tycon applications]
|
| 1803 | 1803 | |
| 1804 | ----------------------------------
|
|
| 1805 | -isSatFamApp :: Type -> Maybe (TyCon, [Type])
|
|
| 1806 | --- Return the argument if we have a saturated type family application
|
|
| 1807 | --- Why saturated? See (ATF4) in Note [Apartness and type families]
|
|
| 1808 | -isSatFamApp (TyConApp tc tys)
|
|
| 1809 | - | isTypeFamilyTyCon tc
|
|
| 1810 | - && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated
|
|
| 1811 | - = Just (tc, tys)
|
|
| 1812 | -isSatFamApp _ = Nothing
|
|
| 1813 | - |
|
| 1814 | 1804 | ---------------------------------
|
| 1815 | 1805 | uVarOrFam :: UMEnv -> CanEqLHS -> InType -> OutCoercion -> UM ()
|
| 1816 | 1806 | -- Invariants: (a) If ty1 is a TyFamLHS, then ty2 is NOT a TyVarTy
|
| ... | ... | @@ -1927,7 +1917,7 @@ uVarOrFam env ty1 ty2 kco |
| 1927 | 1917 | | otherwise -> maybeApart MARTypeFamily
|
| 1928 | 1918 | |
| 1929 | 1919 | -- Check for equality F tys1 ~ F tys2
|
| 1930 | - | Just (tc2, tys2) <- isSatFamApp ty2
|
|
| 1920 | + | Just (tc2, tys2) <- isSatTyFamApp ty2
|
|
| 1931 | 1921 | , tc1 == tc2
|
| 1932 | 1922 | = go_fam_fam substs tc1 tys1 tys2 kco
|
| 1933 | 1923 |
| ... | ... | @@ -363,7 +363,7 @@ pmTopNormaliseType (TySt _ inert) typ = {-# SCC "pmTopNormaliseType" #-} do |
| 363 | 363 | eq_src_ty ty tys = maybe ty id (find is_closed_or_data_family tys)
|
| 364 | 364 | |
| 365 | 365 | is_closed_or_data_family :: Type -> Bool
|
| 366 | - is_closed_or_data_family ty = pmIsClosedType ty || isDataFamilyAppType ty
|
|
| 366 | + is_closed_or_data_family ty = pmIsClosedType ty || isDataFamilyApp ty
|
|
| 367 | 367 | |
| 368 | 368 | -- For efficiency, represent both lists as difference lists.
|
| 369 | 369 | -- comb performs the concatenation, for both lists.
|
| ... | ... | @@ -439,10 +439,9 @@ reportBadTelescope _ _ skol_info skols |
| 439 | 439 | -- See Note [Constraints to ignore].
|
| 440 | 440 | ignoreConstraint :: Ct -> Bool
|
| 441 | 441 | ignoreConstraint ct
|
| 442 | - | AssocFamPatOrigin <- ctOrigin ct
|
|
| 443 | - = True
|
|
| 444 | - | otherwise
|
|
| 445 | - = False
|
|
| 442 | + = case ctOrigin ct of
|
|
| 443 | + AssocFamPatOrigin -> True -- See (CIG1)
|
|
| 444 | + _ -> False
|
|
| 446 | 445 | |
| 447 | 446 | -- | Makes an error item from a constraint, calculating whether or not
|
| 448 | 447 | -- the item should be suppressed. See Note [Wanteds rewrite Wanteds]
|
| ... | ... | @@ -538,15 +537,15 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 538 | 537 | ; when (null simples) $ reportMultiplicityCoercionErrs ctxt_for_insols mult_co_errs
|
| 539 | 538 | |
| 540 | 539 | -- See Note [Suppressing confusing errors]
|
| 541 | - ; let (suppressed_items, items0) = partition suppress tidy_items
|
|
| 540 | + ; let (suppressed_items, reportable_items) = partition suppressItem tidy_items
|
|
| 542 | 541 | ; traceTc "reportWanteds suppressed:" (ppr suppressed_items)
|
| 543 | - ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 items0
|
|
| 542 | + ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 reportable_items
|
|
| 544 | 543 | |
| 545 | 544 | -- Now all the other constraints. We suppress errors here if
|
| 546 | 545 | -- any of the first batch failed, or if the enclosing context
|
| 547 | 546 | -- says to suppress
|
| 548 | 547 | ; let ctxt2 = ctxt1 { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
|
| 549 | - ; (ctxt3, leftovers) <- tryReporters ctxt2 report2 items1
|
|
| 548 | + ; (_, leftovers) <- tryReporters ctxt2 report2 items1
|
|
| 550 | 549 | ; massertPpr (null leftovers)
|
| 551 | 550 | (text "The following unsolved Wanted constraints \
|
| 552 | 551 | \have not been reported to the user:"
|
| ... | ... | @@ -557,12 +556,16 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 557 | 556 | -- wanted insoluble here; but do suppress inner insolubles
|
| 558 | 557 | -- if there's a *given* insoluble here (= inaccessible code)
|
| 559 | 558 | |
| 560 | - -- Only now, if there are no errors, do we report suppressed ones
|
|
| 561 | - -- See Note [Suppressing confusing errors]
|
|
| 562 | - -- We don't need to update the context further because of the
|
|
| 563 | - -- whenNoErrs guard
|
|
| 564 | - ; whenNoErrs $
|
|
| 565 | - do { (_, more_leftovers) <- tryReporters ctxt3 report3 suppressed_items
|
|
| 559 | + -- If there are no other errors to report, report suppressed errors.
|
|
| 560 | + -- See Note [Suppressing confusing errors]. NB: with -fdefer-type-errors
|
|
| 561 | + -- we might have reported warnings only from `reportable_items`, but we
|
|
| 562 | + -- still want to suppress the `suppressed_items`.
|
|
| 563 | + ; when (null reportable_items) $
|
|
| 564 | + do { (_, more_leftovers) <- tryReporters ctxt_for_insols (report1++report2)
|
|
| 565 | + suppressed_items
|
|
| 566 | + -- ctxt_for_insols: the suppressed errors can be Int~Bool, which
|
|
| 567 | + -- will have made the incoming `ctxt` be True; don't make that
|
|
| 568 | + -- suppress the Int~Bool error!
|
|
| 566 | 569 | ; massertPpr (null more_leftovers) (ppr more_leftovers) } }
|
| 567 | 570 | where
|
| 568 | 571 | env = cec_tidy ctxt
|
| ... | ... | @@ -585,29 +588,42 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 585 | 588 | DE_Multiplicity mult_co loc
|
| 586 | 589 | -> (es1, es2, es3, (mult_co, loc):es4)
|
| 587 | 590 | |
| 588 | - -- See Note [Suppressing confusing errors]
|
|
| 589 | - suppress :: ErrorItem -> Bool
|
|
| 590 | - suppress item
|
|
| 591 | - | Wanted <- ei_flavour item
|
|
| 592 | - = is_ww_fundep_item item
|
|
| 593 | - | otherwise
|
|
| 594 | - = False
|
|
| 595 | - |
|
| 596 | 591 | -- report1: ones that should *not* be suppressed by
|
| 597 | 592 | -- an insoluble somewhere else in the tree
|
| 598 | 593 | -- It's crucial that anything that is considered insoluble
|
| 599 | 594 | -- (see GHC.Tc.Utils.insolublWantedCt) is caught here, otherwise
|
| 600 | 595 | -- we might suppress its error message, and proceed on past
|
| 601 | 596 | -- type checking to get a Lint error later
|
| 602 | - report1 = [ ("custom_error", is_user_type_error, True, mkUserTypeErrorReporter)
|
|
| 603 | - -- (Handles TypeError and Unsatisfiable)
|
|
| 597 | + report1 = [ -- We put implicit lifting errors first, because are solid errors
|
|
| 598 | + -- See "Implicit lifting" in GHC.Tc.Gen.Splice
|
|
| 599 | + -- Note [Lifecycle of an untyped splice, and PendingRnSplice]
|
|
| 600 | + ("implicit lifting", is_implicit_lifting, True, mkImplicitLiftingReporter)
|
|
| 604 | 601 | |
| 605 | - , ("implicit lifting", is_implicit_lifting, True, mkImplicitLiftingReporter)
|
|
| 602 | + -- Next, solid equality errors
|
|
| 606 | 603 | , given_eq_spec
|
| 607 | 604 | , ("insoluble2", utterly_wrong, True, mkGroupReporter mkEqErr)
|
| 608 | 605 | , ("skolem eq1", very_wrong, True, mkSkolReporter)
|
| 609 | 606 | , ("FixedRuntimeRep", is_FRR, True, mkGroupReporter mkFRRErr)
|
| 610 | 607 | , ("skolem eq2", skolem_eq, True, mkSkolReporter)
|
| 608 | + |
|
| 609 | + -- Next, custom type errors
|
|
| 610 | + -- See Note [Custom type errors in constraints] in GHC.Tc.Types.Constraint
|
|
| 611 | + --
|
|
| 612 | + -- Put custom type errors /after/ solid equality errors. In #26255 we
|
|
| 613 | + -- had a custom error (T <= F alpha) which was suppressing a far more
|
|
| 614 | + -- informative (K Int ~ [K alpha]). That mismatch between K and [] is
|
|
| 615 | + -- definitely wrong; and if it was fixed we'd know alpha:=Int, and hence
|
|
| 616 | + -- perhaps be able to solve T <= F alpha, by reducing F Int.
|
|
| 617 | + --
|
|
| 618 | + -- But put custom type errors /before/ "non-tv eq", because if we have
|
|
| 619 | + -- () ~ TypeError blah
|
|
| 620 | + -- we want to report it as a custom error, /not/ as a mis-match
|
|
| 621 | + -- between TypeError and ()! Also see the Assert example
|
|
| 622 | + -- in Note [Custom type errors in constraints]
|
|
| 623 | + , ("custom_error", is_user_type_error, True, mkUserTypeErrorReporter)
|
|
| 624 | + -- (Handles TypeError and Unsatisfiable)
|
|
| 625 | + |
|
| 626 | + -- "non-tv-eq": equalities (ty1 ~ ty2) where ty1 is not a tyvar
|
|
| 611 | 627 | , ("non-tv eq", non_tv_eq, True, mkSkolReporter)
|
| 612 | 628 | |
| 613 | 629 | -- The only remaining equalities are alpha ~ ty,
|
| ... | ... | @@ -617,6 +633,7 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 617 | 633 | -- See Note [Equalities with heterogeneous kinds] in GHC.Tc.Solver.Equality
|
| 618 | 634 | , ("Homo eqs", is_homo_equality, True, mkGroupReporter mkEqErr)
|
| 619 | 635 | , ("Other eqs", is_equality, True, mkGroupReporter mkEqErr)
|
| 636 | + |
|
| 620 | 637 | ]
|
| 621 | 638 | |
| 622 | 639 | -- report2: we suppress these if there are insolubles elsewhere in the tree
|
| ... | ... | @@ -625,11 +642,6 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 625 | 642 | , ("Dicts", is_dict, False, mkGroupReporter mkDictErr)
|
| 626 | 643 | , ("Quantified", is_qc, False, mkGroupReporter mkQCErr) ]
|
| 627 | 644 | |
| 628 | - -- report3: suppressed errors should be reported as categorized by either report1
|
|
| 629 | - -- or report2. Keep this in sync with the suppress function above
|
|
| 630 | - report3 = [ ("wanted/wanted fundeps", is_ww_fundep, True, mkGroupReporter mkEqErr)
|
|
| 631 | - ]
|
|
| 632 | - |
|
| 633 | 645 | -- rigid_nom_eq, rigid_nom_tv_eq,
|
| 634 | 646 | is_dict, is_equality, is_ip, is_FRR, is_irred :: ErrorItem -> Pred -> Bool
|
| 635 | 647 | |
| ... | ... | @@ -690,10 +702,6 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 690 | 702 | is_qc _ (ForAllPred {}) = True
|
| 691 | 703 | is_qc _ _ = False
|
| 692 | 704 | |
| 693 | - -- See situation (1) of Note [Suppressing confusing errors]
|
|
| 694 | - is_ww_fundep item _ = is_ww_fundep_item item
|
|
| 695 | - is_ww_fundep_item = isWantedWantedFunDepOrigin . errorItemOrigin
|
|
| 696 | - |
|
| 697 | 705 | given_eq_spec -- See Note [Given errors]
|
| 698 | 706 | | has_gadt_match_here
|
| 699 | 707 | = ("insoluble1a", is_given_eq, True, mkGivenErrorReporter)
|
| ... | ... | @@ -719,6 +727,16 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 719 | 727 | = has_gadt_match implics
|
| 720 | 728 | |
| 721 | 729 | ---------------
|
| 730 | +suppressItem :: ErrorItem -> Bool
|
|
| 731 | + -- See Note [Suppressing confusing errors]
|
|
| 732 | +suppressItem item
|
|
| 733 | + | Wanted <- ei_flavour item
|
|
| 734 | + , let orig = errorItemOrigin item
|
|
| 735 | + = isWantedSuperclassOrigin orig -- See (SCE1)
|
|
| 736 | + || isWantedWantedFunDepOrigin orig -- See (SCE2)
|
|
| 737 | + | otherwise
|
|
| 738 | + = False
|
|
| 739 | + |
|
| 722 | 740 | isSkolemTy :: TcLevel -> Type -> Bool
|
| 723 | 741 | -- The type is a skolem tyvar
|
| 724 | 742 | isSkolemTy tc_lvl ty
|
| ... | ... | @@ -741,9 +759,25 @@ isTyFun_maybe ty = case tcSplitTyConApp_maybe ty of |
| 741 | 759 | Certain errors we might encounter are potentially confusing to users.
|
| 742 | 760 | If there are any other errors to report, at all, we want to suppress these.
|
| 743 | 761 | |
| 744 | -Which errors (only 1 case right now):
|
|
| 745 | - |
|
| 746 | -1) Errors which arise from the interaction of two Wanted fun-dep constraints.
|
|
| 762 | +Which errors are suppressed?
|
|
| 763 | + |
|
| 764 | +(SCE1) Superclasses of Wanteds. These are generated only in case they trigger functional
|
|
| 765 | + dependencies. If such a constraint is unsolved, then its "parent" constraint must
|
|
| 766 | + also be unsolved, and is much more informative to the user. Example (#26255):
|
|
| 767 | + class (MinVersion <= F era) => Era era where { ... }
|
|
| 768 | + f :: forall era. EraFamily era -> IO ()
|
|
| 769 | + f = ..blah... -- [W] Era era
|
|
| 770 | + Here we have simply omitted "Era era =>" from f's type. But we'll end up with
|
|
| 771 | + /two/ Wanted constraints:
|
|
| 772 | + [W] d1 : Era era
|
|
| 773 | + [W] d2 : MinVersion <= F era -- Superclass of d1
|
|
| 774 | + We definitely want to report d1 and not d2! Happily it's easy to filter out those
|
|
| 775 | + superclass-Wanteds, becuase their Origin betrays them.
|
|
| 776 | + |
|
| 777 | + See test T18851 for an example of how it is (just, barely) possible for the /only/
|
|
| 778 | + errors to be superclass-of-Wanted constraints.
|
|
| 779 | + |
|
| 780 | +(SCE2) Errors which arise from the interaction of two Wanted fun-dep constraints.
|
|
| 747 | 781 | Example:
|
| 748 | 782 | |
| 749 | 783 | class C a b | a -> b where
|
| ... | ... | @@ -786,7 +820,7 @@ they will remain unfilled, and might have been used to rewrite another constrain |
| 786 | 820 | |
| 787 | 821 | Currently, the constraints to ignore are:
|
| 788 | 822 | |
| 789 | -1) Constraints generated in order to unify associated type instance parameters
|
|
| 823 | +(CIG1) Constraints generated in order to unify associated type instance parameters
|
|
| 790 | 824 | with class parameters. Here are two illustrative examples:
|
| 791 | 825 | |
| 792 | 826 | class C (a :: k) where
|
| ... | ... | @@ -814,6 +848,9 @@ Currently, the constraints to ignore are: |
| 814 | 848 | |
| 815 | 849 | If there is any trouble, checkValidFamInst bleats, aborting compilation.
|
| 816 | 850 | |
| 851 | +(Note: Aug 25: this seems a rather tricky corner;
|
|
| 852 | + c.f. Note [Suppressing confusing errors])
|
|
| 853 | + |
|
| 817 | 854 | Note [Implementation of Unsatisfiable constraints]
|
| 818 | 855 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 819 | 856 | The Unsatisfiable constraint was introduced in GHC proposal #433 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0433-unsatisfiable.rst).
|
| ... | ... | @@ -903,75 +903,6 @@ isWantedCt = isWanted . ctEvidence |
| 903 | 903 | isGivenCt :: Ct -> Bool
|
| 904 | 904 | isGivenCt = isGiven . ctEvidence
|
| 905 | 905 | |
| 906 | -{- Note [Custom type errors in constraints]
|
|
| 907 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 908 | - |
|
| 909 | -When GHC reports a type-error about an unsolved-constraint, we check
|
|
| 910 | -to see if the constraint contains any custom-type errors, and if so
|
|
| 911 | -we report them. Here are some examples of constraints containing type
|
|
| 912 | -errors:
|
|
| 913 | - |
|
| 914 | -TypeError msg -- The actual constraint is a type error
|
|
| 915 | - |
|
| 916 | -TypError msg ~ Int -- Some type was supposed to be Int, but ended up
|
|
| 917 | - -- being a type error instead
|
|
| 918 | - |
|
| 919 | -Eq (TypeError msg) -- A class constraint is stuck due to a type error
|
|
| 920 | - |
|
| 921 | -F (TypeError msg) ~ a -- A type function failed to evaluate due to a type err
|
|
| 922 | - |
|
| 923 | -It is also possible to have constraints where the type error is nested deeper,
|
|
| 924 | -for example see #11990, and also:
|
|
| 925 | - |
|
| 926 | -Eq (F (TypeError msg)) -- Here the type error is nested under a type-function
|
|
| 927 | - -- call, which failed to evaluate because of it,
|
|
| 928 | - -- and so the `Eq` constraint was unsolved.
|
|
| 929 | - -- This may happen when one function calls another
|
|
| 930 | - -- and the called function produced a custom type error.
|
|
| 931 | --}
|
|
| 932 | - |
|
| 933 | --- | A constraint is considered to be a custom type error, if it contains
|
|
| 934 | --- custom type errors anywhere in it.
|
|
| 935 | --- See Note [Custom type errors in constraints]
|
|
| 936 | -getUserTypeErrorMsg :: PredType -> Maybe ErrorMsgType
|
|
| 937 | -getUserTypeErrorMsg pred = msum $ userTypeError_maybe pred
|
|
| 938 | - : map getUserTypeErrorMsg (subTys pred)
|
|
| 939 | - where
|
|
| 940 | - -- Richard thinks this function is very broken. What is subTys
|
|
| 941 | - -- supposed to be doing? Why are exactly-saturated tyconapps special?
|
|
| 942 | - -- What stops this from accidentally ripping apart a call to TypeError?
|
|
| 943 | - subTys t = case splitAppTys t of
|
|
| 944 | - (t,[]) ->
|
|
| 945 | - case splitTyConApp_maybe t of
|
|
| 946 | - Nothing -> []
|
|
| 947 | - Just (_,ts) -> ts
|
|
| 948 | - (t,ts) -> t : ts
|
|
| 949 | - |
|
| 950 | --- | Is this an user error message type, i.e. either the form @TypeError err@ or
|
|
| 951 | --- @Unsatisfiable err@?
|
|
| 952 | -isTopLevelUserTypeError :: PredType -> Bool
|
|
| 953 | -isTopLevelUserTypeError pred =
|
|
| 954 | - isJust (userTypeError_maybe pred) || isJust (isUnsatisfiableCt_maybe pred)
|
|
| 955 | - |
|
| 956 | --- | Does this constraint contain an user error message?
|
|
| 957 | ---
|
|
| 958 | --- That is, the type is either of the form @Unsatisfiable err@, or it contains
|
|
| 959 | --- a type of the form @TypeError msg@, either at the top level or nested inside
|
|
| 960 | --- the type.
|
|
| 961 | -containsUserTypeError :: PredType -> Bool
|
|
| 962 | -containsUserTypeError pred =
|
|
| 963 | - isJust (getUserTypeErrorMsg pred) || isJust (isUnsatisfiableCt_maybe pred)
|
|
| 964 | - |
|
| 965 | --- | Is this type an unsatisfiable constraint?
|
|
| 966 | --- If so, return the error message.
|
|
| 967 | -isUnsatisfiableCt_maybe :: Type -> Maybe ErrorMsgType
|
|
| 968 | -isUnsatisfiableCt_maybe t
|
|
| 969 | - | Just (tc, [msg]) <- splitTyConApp_maybe t
|
|
| 970 | - , tc `hasKey` unsatisfiableClassNameKey
|
|
| 971 | - = Just msg
|
|
| 972 | - | otherwise
|
|
| 973 | - = Nothing
|
|
| 974 | - |
|
| 975 | 906 | isPendingScDict :: Ct -> Bool
|
| 976 | 907 | isPendingScDict (CDictCan dict_ct) = isPendingScDictCt dict_ct
|
| 977 | 908 | isPendingScDict _ = False
|
| ... | ... | @@ -1413,6 +1344,93 @@ variable masquerading as expression holes IS treated as truly |
| 1413 | 1344 | insoluble, so that it trumps other errors during error reporting.
|
| 1414 | 1345 | Yuk!
|
| 1415 | 1346 | |
| 1347 | +-}
|
|
| 1348 | + |
|
| 1349 | +{- *********************************************************************
|
|
| 1350 | +* *
|
|
| 1351 | + Custom type errors: Unsatisfiable and TypeError
|
|
| 1352 | +* *
|
|
| 1353 | +********************************************************************* -}
|
|
| 1354 | + |
|
| 1355 | +{- Note [Custom type errors in constraints]
|
|
| 1356 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1357 | +When GHC reports a type-error about an unsolved-constraint, we check
|
|
| 1358 | +to see if the constraint contains any custom-type errors, and if so
|
|
| 1359 | +we report them. Here are some examples of constraints containing type
|
|
| 1360 | +errors:
|
|
| 1361 | + |
|
| 1362 | + TypeError msg -- The actual constraint is a type error
|
|
| 1363 | + |
|
| 1364 | + TypError msg ~ Int -- Some type was supposed to be Int, but ended up
|
|
| 1365 | + -- being a type error instead
|
|
| 1366 | + |
|
| 1367 | + Eq (TypeError msg) -- A class constraint is stuck due to a type error
|
|
| 1368 | + |
|
| 1369 | + F (TypeError msg) ~ a -- A type function failed to evaluate due to a type err
|
|
| 1370 | + |
|
| 1371 | +It is also possible to have constraints where the type error is nested deeper,
|
|
| 1372 | +for example see #11990, and also:
|
|
| 1373 | + |
|
| 1374 | + Eq (F (TypeError msg)) -- Here the type error is nested under a type-function
|
|
| 1375 | + -- call, which failed to evaluate because of it,
|
|
| 1376 | + -- and so the `Eq` constraint was unsolved.
|
|
| 1377 | + -- This may happen when one function calls another
|
|
| 1378 | + -- and the called function produced a custom type error.
|
|
| 1379 | + |
|
| 1380 | +A good use-case is described in "Detecting the undetectable"
|
|
| 1381 | + https://blog.csongor.co.uk/report-stuck-families/
|
|
| 1382 | +which features
|
|
| 1383 | + type family Assert (err :: Constraint) (break :: Type -> Type) (a :: k) :: k where
|
|
| 1384 | + Assert _ Dummy _ = Any
|
|
| 1385 | + Assert _ _ k = k
|
|
| 1386 | +and an unsolved constraint like
|
|
| 1387 | + Assert (TypeError ...) (F ty1) ty1 ~ ty2
|
|
| 1388 | +that reports that (F ty1) remains stuck.
|
|
| 1389 | +-}
|
|
| 1390 | + |
|
| 1391 | +-- | A constraint is considered to be a custom type error, if it contains
|
|
| 1392 | +-- custom type errors anywhere in it.
|
|
| 1393 | +-- See Note [Custom type errors in constraints]
|
|
| 1394 | +getUserTypeErrorMsg :: PredType -> Maybe ErrorMsgType
|
|
| 1395 | +getUserTypeErrorMsg pred = msum $ userTypeError_maybe pred
|
|
| 1396 | + : map getUserTypeErrorMsg (subTys pred)
|
|
| 1397 | + where
|
|
| 1398 | + -- Richard thinks this function is very broken. What is subTys
|
|
| 1399 | + -- supposed to be doing? Why are exactly-saturated tyconapps special?
|
|
| 1400 | + -- What stops this from accidentally ripping apart a call to TypeError?
|
|
| 1401 | + subTys t = case splitAppTys t of
|
|
| 1402 | + (t,[]) ->
|
|
| 1403 | + case splitTyConApp_maybe t of
|
|
| 1404 | + Nothing -> []
|
|
| 1405 | + Just (_,ts) -> ts
|
|
| 1406 | + (t,ts) -> t : ts
|
|
| 1407 | + |
|
| 1408 | +-- | Is this an user error message type, i.e. either the form @TypeError err@ or
|
|
| 1409 | +-- @Unsatisfiable err@?
|
|
| 1410 | +isTopLevelUserTypeError :: PredType -> Bool
|
|
| 1411 | +isTopLevelUserTypeError pred =
|
|
| 1412 | + isJust (userTypeError_maybe pred) || isJust (isUnsatisfiableCt_maybe pred)
|
|
| 1413 | + |
|
| 1414 | +-- | Does this constraint contain an user error message?
|
|
| 1415 | +--
|
|
| 1416 | +-- That is, the type is either of the form @Unsatisfiable err@, or it contains
|
|
| 1417 | +-- a type of the form @TypeError msg@, either at the top level or nested inside
|
|
| 1418 | +-- the type.
|
|
| 1419 | +containsUserTypeError :: PredType -> Bool
|
|
| 1420 | +containsUserTypeError pred =
|
|
| 1421 | + isJust (getUserTypeErrorMsg pred) || isJust (isUnsatisfiableCt_maybe pred)
|
|
| 1422 | + |
|
| 1423 | +-- | Is this type an unsatisfiable constraint?
|
|
| 1424 | +-- If so, return the error message.
|
|
| 1425 | +isUnsatisfiableCt_maybe :: Type -> Maybe ErrorMsgType
|
|
| 1426 | +isUnsatisfiableCt_maybe t
|
|
| 1427 | + | Just (tc, [msg]) <- splitTyConApp_maybe t
|
|
| 1428 | + , tc `hasKey` unsatisfiableClassNameKey
|
|
| 1429 | + = Just msg
|
|
| 1430 | + | otherwise
|
|
| 1431 | + = Nothing
|
|
| 1432 | + |
|
| 1433 | +{-
|
|
| 1416 | 1434 | ************************************************************************
|
| 1417 | 1435 | * *
|
| 1418 | 1436 | Implication constraints
|
| ... | ... | @@ -2090,6 +2090,7 @@ isRigidTy ty |
| 2090 | 2090 | | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal
|
| 2091 | 2091 | | Just {} <- tcSplitAppTy_maybe ty = True
|
| 2092 | 2092 | | isForAllTy ty = True
|
| 2093 | + | Just {} <- isLitTy ty = True
|
|
| 2093 | 2094 | | otherwise = False
|
| 2094 | 2095 | |
| 2095 | 2096 | {-
|
| ... | ... | @@ -33,3 +33,14 @@ f = show (undefined :: c) |
| 33 | 33 | -- blows up at run time once type checks
|
| 34 | 34 | g :: String
|
| 35 | 35 | g = f @A @B
|
| 36 | + |
|
| 37 | +{-
|
|
| 38 | +[W] Show c, Num int, C int A, C int B, C int c
|
|
| 39 | +Superclasses
|
|
| 40 | + C_FD int ~ A
|
|
| 41 | + C_FD int ~ B
|
|
| 42 | + C_FD int ~ c
|
|
| 43 | +-->
|
|
| 44 | + C_FD int ~ B
|
|
| 45 | + B ~ A
|
|
| 46 | +-} |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 2 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
| 3 | +{-# LANGUAGE TypeFamilyDependencies #-}
|
|
| 4 | +{-# LANGUAGE UndecidableSuperClasses #-}
|
|
| 5 | + |
|
| 6 | +module T26255a where
|
|
| 7 | + |
|
| 8 | +import Data.Proxy
|
|
| 9 | +import GHC.TypeLits
|
|
| 10 | + |
|
| 11 | +type MinVersion = 1
|
|
| 12 | + |
|
| 13 | +class
|
|
| 14 | + ( KnownNat (ProtVerLow era)
|
|
| 15 | + , MinVersion <= ProtVerLow era
|
|
| 16 | + , KnownSymbol (EraName era)
|
|
| 17 | + ) =>
|
|
| 18 | + Era era
|
|
| 19 | + where
|
|
| 20 | + type EraName era = (r :: Symbol) | r -> era
|
|
| 21 | + |
|
| 22 | + type ProtVerLow era :: Nat
|
|
| 23 | + |
|
| 24 | + eraName :: Proxy era -> String
|
|
| 25 | + eraName _ = symbolVal (Proxy :: Proxy (EraName era))
|
|
| 26 | + |
|
| 27 | +data FooEra
|
|
| 28 | + |
|
| 29 | +instance Era FooEra where
|
|
| 30 | + type EraName FooEra = "Foo"
|
|
| 31 | + type ProtVerLow FooEra = 1
|
|
| 32 | + |
|
| 33 | +data BarEra
|
|
| 34 | + |
|
| 35 | +instance Era BarEra where
|
|
| 36 | + type EraName BarEra = "Bar"
|
|
| 37 | + type ProtVerLow BarEra = 2
|
|
| 38 | + |
|
| 39 | +fromEraName :: (Era era, EraName era ~ name) => Proxy (name :: Symbol) -> Proxy era
|
|
| 40 | +fromEraName _ = Proxy
|
|
| 41 | + |
|
| 42 | +noCompileErrorMessage :: IO ()
|
|
| 43 | +noCompileErrorMessage = putStrLn $ eraName $ fromEraName (Proxy :: Proxy "Bar")
|
|
| 44 | + |
|
| 45 | +brokenCompileErrorMessage1 :: IO ()
|
|
| 46 | +brokenCompileErrorMessage1 = putStrLn $ eraName $ fromEraName (Proxy :: Proxy "Blah")
|
|
| 47 | + |
| 1 | +T26255a.hs:46:51: error: [GHC-18872]
|
|
| 2 | + • Couldn't match type ‘EraName era0’ with ‘"Blah"’
|
|
| 3 | + arising from a use of ‘fromEraName’
|
|
| 4 | + The type variable ‘era0’ is ambiguous
|
|
| 5 | + • In the second argument of ‘($)’, namely
|
|
| 6 | + ‘fromEraName (Proxy :: Proxy "Blah")’
|
|
| 7 | + In the second argument of ‘($)’, namely
|
|
| 8 | + ‘eraName $ fromEraName (Proxy :: Proxy "Blah")’
|
|
| 9 | + In the expression:
|
|
| 10 | + putStrLn $ eraName $ fromEraName (Proxy :: Proxy "Blah") |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 2 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
| 3 | +{-# LANGUAGE TypeFamilyDependencies #-}
|
|
| 4 | +{-# LANGUAGE UndecidableSuperClasses #-}
|
|
| 5 | + |
|
| 6 | +module T26255b where
|
|
| 7 | + |
|
| 8 | +import Data.Proxy
|
|
| 9 | +import GHC.TypeLits
|
|
| 10 | + |
|
| 11 | +type MinVersion = 1
|
|
| 12 | + |
|
| 13 | +class
|
|
| 14 | + ( KnownNat (ProtVerLow era)
|
|
| 15 | + , MinVersion <= ProtVerLow era
|
|
| 16 | + , KnownSymbol (EraName era)
|
|
| 17 | + ) =>
|
|
| 18 | + Era era
|
|
| 19 | + where
|
|
| 20 | + type EraName era = (r :: Symbol) | r -> era
|
|
| 21 | + |
|
| 22 | + type ProtVerLow era :: Nat
|
|
| 23 | + |
|
| 24 | + eraName :: Proxy era -> String
|
|
| 25 | + eraName _ = symbolVal (Proxy :: Proxy (EraName era))
|
|
| 26 | + |
|
| 27 | +data FooEra
|
|
| 28 | + |
|
| 29 | +instance Era FooEra where
|
|
| 30 | + type EraName FooEra = "Foo"
|
|
| 31 | + type ProtVerLow FooEra = 1
|
|
| 32 | + |
|
| 33 | +data BarEra
|
|
| 34 | + |
|
| 35 | +instance Era BarEra where
|
|
| 36 | + type EraName BarEra = "Bar"
|
|
| 37 | + type ProtVerLow BarEra = 2
|
|
| 38 | + |
|
| 39 | +fromEraName :: (Era era, EraName era ~ name) => Proxy (name :: Symbol) -> Proxy era
|
|
| 40 | +fromEraName _ = Proxy
|
|
| 41 | + |
|
| 42 | +noCompileErrorMessage :: IO ()
|
|
| 43 | +noCompileErrorMessage = putStrLn $ eraName $ fromEraName (Proxy :: Proxy "Bar")
|
|
| 44 | + |
|
| 45 | +brokenCompileErrorMessage2 :: IO ()
|
|
| 46 | +brokenCompileErrorMessage2 = putStrLn $ eraName $ head $ fromEraName (Proxy :: Proxy "Bar") |
| 1 | +T26255b.hs:46:58: error: [GHC-83865]
|
|
| 2 | + • Couldn't match expected type: [Proxy era0]
|
|
| 3 | + with actual type: Proxy BarEra
|
|
| 4 | + • In the second argument of ‘($)’, namely
|
|
| 5 | + ‘fromEraName (Proxy :: Proxy "Bar")’
|
|
| 6 | + In the second argument of ‘($)’, namely
|
|
| 7 | + ‘head $ fromEraName (Proxy :: Proxy "Bar")’
|
|
| 8 | + In the second argument of ‘($)’, namely
|
|
| 9 | + ‘eraName $ head $ fromEraName (Proxy :: Proxy "Bar")’ |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 2 | +{-# LANGUAGE FlexibleContexts #-}
|
|
| 3 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
| 4 | +{-# LANGUAGE TypeFamilyDependencies #-}
|
|
| 5 | +{-# LANGUAGE TypeOperators #-}
|
|
| 6 | +{-# LANGUAGE UndecidableSuperClasses #-}
|
|
| 7 | + |
|
| 8 | +module T26255c where
|
|
| 9 | + |
|
| 10 | +import Data.Kind
|
|
| 11 | +import Data.Proxy
|
|
| 12 | +import GHC.TypeLits
|
|
| 13 | + |
|
| 14 | +type MinVersion = 1
|
|
| 15 | + |
|
| 16 | +class
|
|
| 17 | + ( KnownNat (ProtVerLow era)
|
|
| 18 | + , MinVersion <= ProtVerLow era
|
|
| 19 | + ) =>
|
|
| 20 | + Era era
|
|
| 21 | + where
|
|
| 22 | + type ProtVerLow era :: Nat
|
|
| 23 | + |
|
| 24 | +newtype EraFamily era = EraFamily Int
|
|
| 25 | + |
|
| 26 | +class Era era => NewEra era where
|
|
| 27 | + eraFamilySize :: EraFamily era -> Int
|
|
| 28 | + |
|
| 29 | +printEraFamilySize :: EraFamily era -> IO ()
|
|
| 30 | +printEraFamilySize = print . eraFamilySize |
| 1 | +T26255c.hs:30:30: error: [GHC-39999]
|
|
| 2 | + • No instance for ‘NewEra era’
|
|
| 3 | + arising from a use of ‘eraFamilySize’
|
|
| 4 | + Possible fix:
|
|
| 5 | + add (NewEra era) to the context of
|
|
| 6 | + the type signature for:
|
|
| 7 | + printEraFamilySize :: forall {k} (era :: k). EraFamily era -> IO ()
|
|
| 8 | + • In the second argument of ‘(.)’, namely ‘eraFamilySize’
|
|
| 9 | + In the expression: print . eraFamilySize
|
|
| 10 | + In an equation for ‘printEraFamilySize’:
|
|
| 11 | + printEraFamilySize = print . eraFamilySize |
| 1 | +UnliftedNewtypesFamilyKindFail2.hs:12:1: error: [GHC-83865]
|
|
| 2 | + • Expected a type, but ‘F 5’ has kind ‘5’
|
|
| 3 | + • In the newtype family instance declaration for ‘F’
|
|
| 4 | + |
|
| 1 | 5 | UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865]
|
| 2 | 6 | • Expected a type,
|
| 3 | 7 | but ‘5’ has kind
|
| ... | ... | @@ -742,3 +742,5 @@ test('T25004', normal, compile_fail, ['']) |
| 742 | 742 | test('T25004k', normal, compile_fail, [''])
|
| 743 | 743 | test('T26004', normal, compile_fail, [''])
|
| 744 | 744 | test('T26318', normal, compile_fail, [''])
|
| 745 | +test('T26255a', normal, compile_fail, [''])
|
|
| 746 | +test('T26255b', normal, compile_fail, ['']) |