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, ['']) |