Simon Peyton Jones pushed to branch wip/T26255 at Glasgow Haskell Compiler / GHC
Commits:
-
5b5d9d47
by Ben Gamari at 2025-08-25T14:29:35-04:00
-
10f06163
by Cheng Shao at 2025-08-25T14:30:16-04:00
-
bedc1004
by Cheng Shao at 2025-08-26T09:31:18-04:00
-
13250d97
by Ryan Scott at 2025-08-26T09:31:59-04:00
-
ca1b9bea
by Simon Peyton Jones at 2025-08-26T17:30:29+01:00
26 changed files:
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Utils/TcType.hs
- docs/users_guide/9.16.1-notes.rst
- rts/PrimOps.cmm
- rts/RaiseAsync.c
- rts/STM.c
- − testsuite/tests/lib/stm/T26028.hs
- − testsuite/tests/lib/stm/T26028.stdout
- − testsuite/tests/lib/stm/all.T
- 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/T26318.hs
- + testsuite/tests/typecheck/should_fail/T26318.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/jsffi/dyld.mjs
Changes:
| ... | ... | @@ -83,6 +83,7 @@ import GHC.Data.Word64Map.Strict (Word64Map) |
| 83 | 83 | import qualified GHC.Data.Word64Map.Strict as M
|
| 84 | 84 | import GHC.Data.TrieMap
|
| 85 | 85 | |
| 86 | +import Data.Coerce
|
|
| 86 | 87 | import Data.Word (Word64)
|
| 87 | 88 | |
| 88 | 89 | |
| ... | ... | @@ -164,7 +165,7 @@ setFoldr k z (LS s) = S.foldr (\v a -> k (mkHooplLabel v) a) z s |
| 164 | 165 | |
| 165 | 166 | {-# INLINE setElems #-}
|
| 166 | 167 | setElems :: LabelSet -> [Label]
|
| 167 | -setElems (LS s) = map mkHooplLabel (S.elems s)
|
|
| 168 | +setElems (LS s) = coerce $ S.elems s
|
|
| 168 | 169 | |
| 169 | 170 | {-# INLINE setFromList #-}
|
| 170 | 171 | setFromList :: [Label] -> LabelSet
|
| ... | ... | @@ -272,7 +273,7 @@ mapKeys (LM m) = map (mkHooplLabel . fst) (M.toList m) |
| 272 | 273 | |
| 273 | 274 | {-# INLINE mapToList #-}
|
| 274 | 275 | mapToList :: LabelMap b -> [(Label, b)]
|
| 275 | -mapToList (LM m) = [(mkHooplLabel k, v) | (k, v) <- M.toList m]
|
|
| 276 | +mapToList (LM m) = coerce $ M.toList m
|
|
| 276 | 277 | |
| 277 | 278 | {-# INLINE mapFromList #-}
|
| 278 | 279 | mapFromList :: [(Label, v)] -> LabelMap v
|
| ... | ... | @@ -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,
|
| ... | ... | @@ -2295,6 +2295,21 @@ isFamFreeTy (ForAllTy _ ty) = isFamFreeTy ty |
| 2295 | 2295 | isFamFreeTy (CastTy ty _) = isFamFreeTy ty
|
| 2296 | 2296 | isFamFreeTy (CoercionTy _) = False -- Not sure about this
|
| 2297 | 2297 | |
| 2298 | +-- | Check whether a type is a data family type
|
|
| 2299 | +isDataFamilyApp :: Type -> Bool
|
|
| 2300 | +isDataFamilyApp ty = case tyConAppTyCon_maybe ty of
|
|
| 2301 | + Just tc -> isDataFamilyTyCon tc
|
|
| 2302 | + _ -> False
|
|
| 2303 | + |
|
| 2304 | +isSatTyFamApp :: Type -> Maybe (TyCon, [Type])
|
|
| 2305 | +-- Return the argument if we have a saturated type family application
|
|
| 2306 | +-- Why saturated? See (ATF4) in Note [Apartness and type families]
|
|
| 2307 | +isSatTyFamApp (TyConApp tc tys)
|
|
| 2308 | + | isTypeFamilyTyCon tc
|
|
| 2309 | + && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated
|
|
| 2310 | + = Just (tc, tys)
|
|
| 2311 | +isSatTyFamApp _ = Nothing
|
|
| 2312 | + |
|
| 2298 | 2313 | buildSynTyCon :: Name -> [KnotTied TyConBinder] -> Kind -- ^ /result/ kind
|
| 2299 | 2314 | -> [Role] -> KnotTied Type -> TyCon
|
| 2300 | 2315 | -- This function is here because here is where we have
|
| ... | ... | @@ -2462,12 +2477,6 @@ isAlgType ty |
| 2462 | 2477 | isAlgTyCon tc
|
| 2463 | 2478 | _other -> False
|
| 2464 | 2479 | |
| 2465 | --- | Check whether a type is a data family type
|
|
| 2466 | -isDataFamilyAppType :: Type -> Bool
|
|
| 2467 | -isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of
|
|
| 2468 | - Just tc -> isDataFamilyTyCon tc
|
|
| 2469 | - _ -> False
|
|
| 2470 | - |
|
| 2471 | 2480 | -- | Computes whether an argument (or let right hand side) should
|
| 2472 | 2481 | -- be computed strictly or lazily, based only on its type.
|
| 2473 | 2482 | -- Currently, it's just 'isUnliftedType'.
|
| ... | ... | @@ -1690,8 +1690,8 @@ unify_ty env ty1 ty2 kco |
| 1690 | 1690 | where
|
| 1691 | 1691 | mb_tc_app1 = splitTyConApp_maybe ty1
|
| 1692 | 1692 | mb_tc_app2 = splitTyConApp_maybe ty2
|
| 1693 | - mb_sat_fam_app1 = isSatFamApp ty1
|
|
| 1694 | - mb_sat_fam_app2 = isSatFamApp ty2
|
|
| 1693 | + mb_sat_fam_app1 = isSatTyFamApp ty1
|
|
| 1694 | + mb_sat_fam_app2 = isSatTyFamApp ty2
|
|
| 1695 | 1695 | |
| 1696 | 1696 | unify_ty _ _ _ _ = surelyApart
|
| 1697 | 1697 | |
| ... | ... | @@ -1750,16 +1750,6 @@ unify_tys env orig_xs orig_ys |
| 1750 | 1750 | -- Possibly different saturations of a polykinded tycon
|
| 1751 | 1751 | -- See Note [Polykinded tycon applications]
|
| 1752 | 1752 | |
| 1753 | ----------------------------------
|
|
| 1754 | -isSatFamApp :: Type -> Maybe (TyCon, [Type])
|
|
| 1755 | --- Return the argument if we have a saturated type family application
|
|
| 1756 | --- Why saturated? See (ATF4) in Note [Apartness and type families]
|
|
| 1757 | -isSatFamApp (TyConApp tc tys)
|
|
| 1758 | - | isTypeFamilyTyCon tc
|
|
| 1759 | - && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated
|
|
| 1760 | - = Just (tc, tys)
|
|
| 1761 | -isSatFamApp _ = Nothing
|
|
| 1762 | - |
|
| 1763 | 1753 | ---------------------------------
|
| 1764 | 1754 | uVarOrFam :: UMEnv -> CanEqLHS -> InType -> OutCoercion -> UM ()
|
| 1765 | 1755 | -- Invariants: (a) If ty1 is a TyFamLHS, then ty2 is NOT a TyVarTy
|
| ... | ... | @@ -1876,7 +1866,7 @@ uVarOrFam env ty1 ty2 kco |
| 1876 | 1866 | | otherwise -> maybeApart MARTypeFamily
|
| 1877 | 1867 | |
| 1878 | 1868 | -- Check for equality F tys1 ~ F tys2
|
| 1879 | - | Just (tc2, tys2) <- isSatFamApp ty2
|
|
| 1869 | + | Just (tc2, tys2) <- isSatTyFamApp ty2
|
|
| 1880 | 1870 | , tc1 == tc2
|
| 1881 | 1871 | = go_fam_fam tc1 tys1 tys2 kco
|
| 1882 | 1872 |
| ... | ... | @@ -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.
|
| ... | ... | @@ -547,15 +547,7 @@ rnHsTyKi env tv@(HsTyVar _ ip (L loc rdr_name)) |
| 547 | 547 | ; this_mod <- getModule
|
| 548 | 548 | ; when (nameIsLocalOrFrom this_mod name) $
|
| 549 | 549 | checkThLocalTyName name
|
| 550 | - ; when (isDataConName name && not (isKindName name)) $
|
|
| 551 | - -- Any use of a promoted data constructor name (that is not
|
|
| 552 | - -- specifically exempted by isKindName) is illegal without the use
|
|
| 553 | - -- of DataKinds. See Note [Checking for DataKinds] in
|
|
| 554 | - -- GHC.Tc.Validity.
|
|
| 555 | - checkDataKinds env tv
|
|
| 556 | - ; when (isDataConName name && not (isPromoted ip)) $
|
|
| 557 | - -- NB: a prefix symbolic operator such as (:) is represented as HsTyVar.
|
|
| 558 | - addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Prefix name)
|
|
| 550 | + ; checkPromotedDataConName env tv Prefix ip name
|
|
| 559 | 551 | ; return (HsTyVar noAnn ip (L loc $ WithUserRdr rdr_name name), unitFV name) }
|
| 560 | 552 | |
| 561 | 553 | rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
|
| ... | ... | @@ -567,8 +559,7 @@ rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2) |
| 567 | 559 | ; (ty1', fvs2) <- rnLHsTyKi env ty1
|
| 568 | 560 | ; (ty2', fvs3) <- rnLHsTyKi env ty2
|
| 569 | 561 | ; res_ty <- mkHsOpTyRn prom (fmap (WithUserRdr op_rdr) l_op') fix ty1' ty2'
|
| 570 | - ; when (isDataConName op_name && not (isPromoted prom)) $
|
|
| 571 | - addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Infix op_name)
|
|
| 562 | + ; checkPromotedDataConName env ty Infix prom op_name
|
|
| 572 | 563 | ; return (res_ty, plusFVs [fvs1, fvs2, fvs3]) }
|
| 573 | 564 | |
| 574 | 565 | rnHsTyKi env (HsParTy _ ty)
|
| ... | ... | @@ -1670,6 +1661,30 @@ checkDataKinds env thing |
| 1670 | 1661 | type_or_kind | isRnKindLevel env = KindLevel
|
| 1671 | 1662 | | otherwise = TypeLevel
|
| 1672 | 1663 | |
| 1664 | +-- | If a 'Name' is that of a promoted data constructor, perform various
|
|
| 1665 | +-- validity checks on it.
|
|
| 1666 | +checkPromotedDataConName ::
|
|
| 1667 | + RnTyKiEnv ->
|
|
| 1668 | + -- | The type that the 'Name' belongs to. This will always be an 'HsTyVar'
|
|
| 1669 | + -- (for 'Prefix' names) or an 'HsOpTy' (for 'Infix' names).
|
|
| 1670 | + HsType GhcPs ->
|
|
| 1671 | + -- | Whether the type is written 'Prefix' or 'Infix'.
|
|
| 1672 | + LexicalFixity ->
|
|
| 1673 | + -- | Whether the name was written with an explicit promotion tick or not.
|
|
| 1674 | + PromotionFlag ->
|
|
| 1675 | + -- | The name to check.
|
|
| 1676 | + Name ->
|
|
| 1677 | + TcM ()
|
|
| 1678 | +checkPromotedDataConName env ty fixity ip name
|
|
| 1679 | + = do when (isDataConName name && not (isKindName name)) $
|
|
| 1680 | + -- Any use of a promoted data constructor name (that is not
|
|
| 1681 | + -- specifically exempted by isKindName) is illegal without the use
|
|
| 1682 | + -- of DataKinds. See Note [Checking for DataKinds] in
|
|
| 1683 | + -- GHC.Tc.Validity.
|
|
| 1684 | + checkDataKinds env ty
|
|
| 1685 | + when (isDataConName name && not (isPromoted ip)) $
|
|
| 1686 | + addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor fixity name)
|
|
| 1687 | + |
|
| 1673 | 1688 | warnUnusedForAll :: OutputableBndrFlag flag 'Renamed
|
| 1674 | 1689 | => HsDocContext -> LHsTyVarBndr flag GhcRn -> FreeVars -> TcM ()
|
| 1675 | 1690 | warnUnusedForAll doc (L loc tvb) used_names =
|
| ... | ... | @@ -50,6 +50,8 @@ import GHC.Types.Name.Env |
| 50 | 50 | import GHC.Types.SrcLoc
|
| 51 | 51 | import GHC.Types.Basic
|
| 52 | 52 | import GHC.Types.Error
|
| 53 | +import GHC.Types.Unique( hasKey )
|
|
| 54 | +import GHC.Builtin.Names( errorMessageTypeErrorFamKey )
|
|
| 53 | 55 | import qualified GHC.Types.Unique.Map as UM
|
| 54 | 56 | |
| 55 | 57 | import GHC.Unit.Module
|
| ... | ... | @@ -439,10 +441,9 @@ reportBadTelescope _ _ skol_info skols |
| 439 | 441 | -- See Note [Constraints to ignore].
|
| 440 | 442 | ignoreConstraint :: Ct -> Bool
|
| 441 | 443 | ignoreConstraint ct
|
| 442 | - | AssocFamPatOrigin <- ctOrigin ct
|
|
| 443 | - = True
|
|
| 444 | - | otherwise
|
|
| 445 | - = False
|
|
| 444 | + = case ctOrigin ct of
|
|
| 445 | + AssocFamPatOrigin -> True -- See (CIG1)
|
|
| 446 | + _ -> False
|
|
| 446 | 447 | |
| 447 | 448 | -- | Makes an error item from a constraint, calculating whether or not
|
| 448 | 449 | -- the item should be suppressed. See Note [Wanteds rewrite Wanteds]
|
| ... | ... | @@ -538,7 +539,7 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 538 | 539 | ; when (null simples) $ reportMultiplicityCoercionErrs ctxt_for_insols mult_co_errs
|
| 539 | 540 | |
| 540 | 541 | -- See Note [Suppressing confusing errors]
|
| 541 | - ; let (suppressed_items, items0) = partition suppress tidy_items
|
|
| 542 | + ; let (suppressed_items, items0) = partition suppressItem tidy_items
|
|
| 542 | 543 | ; traceTc "reportWanteds suppressed:" (ppr suppressed_items)
|
| 543 | 544 | ; (ctxt1, items1) <- tryReporters ctxt_for_insols report1 items0
|
| 544 | 545 | |
| ... | ... | @@ -546,7 +547,7 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 546 | 547 | -- any of the first batch failed, or if the enclosing context
|
| 547 | 548 | -- says to suppress
|
| 548 | 549 | ; let ctxt2 = ctxt1 { cec_suppress = cec_suppress ctxt || cec_suppress ctxt1 }
|
| 549 | - ; (ctxt3, leftovers) <- tryReporters ctxt2 report2 items1
|
|
| 550 | + ; (_, leftovers) <- tryReporters ctxt2 report2 items1
|
|
| 550 | 551 | ; massertPpr (null leftovers)
|
| 551 | 552 | (text "The following unsolved Wanted constraints \
|
| 552 | 553 | \have not been reported to the user:"
|
| ... | ... | @@ -557,12 +558,16 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 557 | 558 | -- wanted insoluble here; but do suppress inner insolubles
|
| 558 | 559 | -- if there's a *given* insoluble here (= inaccessible code)
|
| 559 | 560 | |
| 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
|
|
| 561 | + -- If there are no other errors to report, report suppressed errors.
|
|
| 562 | + -- See Note [Suppressing confusing errors]. NB: with -fdefer-type-errors
|
|
| 563 | + -- we might have reported warnings only from `items0`, but we still want to
|
|
| 564 | + -- suppress the `suppressed_items`.
|
|
| 565 | + ; when (null items0) $
|
|
| 566 | + do { (_, more_leftovers) <- tryReporters ctxt_for_insols (report1++report2)
|
|
| 567 | + suppressed_items
|
|
| 568 | + -- ctxt_for_insols: the suppressed errors can be Int~Bool, which
|
|
| 569 | + -- will have made the incoming `ctxt` be True; don't make that suppress
|
|
| 570 | + -- the Int~Bool error!
|
|
| 566 | 571 | ; massertPpr (null more_leftovers) (ppr more_leftovers) } }
|
| 567 | 572 | where
|
| 568 | 573 | env = cec_tidy ctxt
|
| ... | ... | @@ -585,29 +590,49 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 585 | 590 | DE_Multiplicity mult_co loc
|
| 586 | 591 | -> (es1, es2, es3, (mult_co, loc):es4)
|
| 587 | 592 | |
| 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 | 593 | -- report1: ones that should *not* be suppressed by
|
| 597 | 594 | -- an insoluble somewhere else in the tree
|
| 598 | 595 | -- It's crucial that anything that is considered insoluble
|
| 599 | 596 | -- (see GHC.Tc.Utils.insolublWantedCt) is caught here, otherwise
|
| 600 | 597 | -- we might suppress its error message, and proceed on past
|
| 601 | 598 | -- type checking to get a Lint error later
|
| 602 | - report1 = [ ("custom_error", is_user_type_error, True, mkUserTypeErrorReporter)
|
|
| 603 | - -- (Handles TypeError and Unsatisfiable)
|
|
| 599 | + report1 = [ -- We put implicit lifting errors first, because are solid errors
|
|
| 600 | + -- See "Implicit lifting" in GHC.Tc.Gen.Splice
|
|
| 601 | + -- Note [Lifecycle of an untyped splice, and PendingRnSplice]
|
|
| 602 | + ("implicit lifting", is_implicit_lifting, True, mkImplicitLiftingReporter)
|
|
| 604 | 603 | |
| 605 | - , ("implicit lifting", is_implicit_lifting, True, mkImplicitLiftingReporter)
|
|
| 604 | + -- Next, solid equality errors
|
|
| 606 | 605 | , given_eq_spec
|
| 607 | 606 | , ("insoluble2", utterly_wrong, True, mkGroupReporter mkEqErr)
|
| 608 | 607 | , ("skolem eq1", very_wrong, True, mkSkolReporter)
|
| 609 | 608 | , ("FixedRuntimeRep", is_FRR, True, mkGroupReporter mkFRRErr)
|
| 610 | 609 | , ("skolem eq2", skolem_eq, True, mkSkolReporter)
|
| 610 | + |
|
| 611 | + -- Next, family applications like (F t1 t2 ~ rigid_ty)
|
|
| 612 | + -- These could be solved by doing a type-family reduction for F
|
|
| 613 | + -- which probably means fixing a unfication variable in t1/t2
|
|
| 614 | + -- See discussion in #26255, where F had an injectivity annotation,
|
|
| 615 | + -- and we had [W] F alpha ~ "foo"
|
|
| 616 | + -- The real error is that the "foo" should be "bar", because there is
|
|
| 617 | + -- type instance F Int = "bar"
|
|
| 618 | + -- We could additionally filter on the injectivty annotation,
|
|
| 619 | + -- but currently we don't.
|
|
| 620 | + , ("fam app", is_fam_app_eq, True, mkGroupReporter mkEqErr)
|
|
| 621 | + |
|
| 622 | + -- Put custom type errors after solid equality errors. In #26255 we
|
|
| 623 | + -- had a custom error (T <= F alpha) which was suppressing a far more
|
|
| 624 | + -- informative (K Int ~ [K alpha]). That mismatch between K and [] is
|
|
| 625 | + -- definitely wrong; and if it was fixed we'd know alpha:=Int, and hence
|
|
| 626 | + -- perhaps be able to solve T <= F alpha, by reducing F Int.
|
|
| 627 | + --
|
|
| 628 | + -- Custom errors should precede "non-tv eq", becuase if we have
|
|
| 629 | + -- () ~ TypeError blah
|
|
| 630 | + -- we want to report it as a custom error, /not/ as a mis-match
|
|
| 631 | + -- between TypeError and ()!
|
|
| 632 | + , ("custom_error", is_user_type_error, True, mkUserTypeErrorReporter)
|
|
| 633 | + -- (Handles TypeError and Unsatisfiable)
|
|
| 634 | + |
|
| 635 | + -- "non-tv-eq": equalities (ty1 ~ ty2) where ty1 is not a tyvar
|
|
| 611 | 636 | , ("non-tv eq", non_tv_eq, True, mkSkolReporter)
|
| 612 | 637 | |
| 613 | 638 | -- The only remaining equalities are alpha ~ ty,
|
| ... | ... | @@ -617,6 +642,7 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 617 | 642 | -- See Note [Equalities with heterogeneous kinds] in GHC.Tc.Solver.Equality
|
| 618 | 643 | , ("Homo eqs", is_homo_equality, True, mkGroupReporter mkEqErr)
|
| 619 | 644 | , ("Other eqs", is_equality, True, mkGroupReporter mkEqErr)
|
| 645 | + |
|
| 620 | 646 | ]
|
| 621 | 647 | |
| 622 | 648 | -- report2: we suppress these if there are insolubles elsewhere in the tree
|
| ... | ... | @@ -625,11 +651,6 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 625 | 651 | , ("Dicts", is_dict, False, mkGroupReporter mkDictErr)
|
| 626 | 652 | , ("Quantified", is_qc, False, mkGroupReporter mkQCErr) ]
|
| 627 | 653 | |
| 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 | 654 | -- rigid_nom_eq, rigid_nom_tv_eq,
|
| 634 | 655 | is_dict, is_equality, is_ip, is_FRR, is_irred :: ErrorItem -> Pred -> Bool
|
| 635 | 656 | |
| ... | ... | @@ -650,6 +671,13 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 650 | 671 | -- Representation-polymorphism errors, to be reported using mkFRRErr.
|
| 651 | 672 | is_FRR item _ = isJust $ fixedRuntimeRepOrigin_maybe item
|
| 652 | 673 | |
| 674 | + -- Things like (F t1 t2 ~N Maybe s)
|
|
| 675 | + -- But only proper type families; not (TypeError t1 t2 ~N blah)
|
|
| 676 | + is_fam_app_eq _ (EqPred NomEq ty1 ty2)
|
|
| 677 | + | Just (tc,_) <- isSatTyFamApp ty1
|
|
| 678 | + = not (tc `hasKey` errorMessageTypeErrorFamKey) && isRigidTy ty2
|
|
| 679 | + is_fam_app_eq _ _ = False
|
|
| 680 | + |
|
| 653 | 681 | -- Things like (a ~N b) or (a ~N F Bool)
|
| 654 | 682 | skolem_eq _ (EqPred NomEq ty1 _) = isSkolemTy tc_lvl ty1
|
| 655 | 683 | skolem_eq _ _ = False
|
| ... | ... | @@ -690,10 +718,6 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 690 | 718 | is_qc _ (ForAllPred {}) = True
|
| 691 | 719 | is_qc _ _ = False
|
| 692 | 720 | |
| 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 | 721 | given_eq_spec -- See Note [Given errors]
|
| 698 | 722 | | has_gadt_match_here
|
| 699 | 723 | = ("insoluble1a", is_given_eq, True, mkGivenErrorReporter)
|
| ... | ... | @@ -719,6 +743,16 @@ reportWanteds ctxt tc_lvl wc@(WC { wc_simple = simples, wc_impl = implics |
| 719 | 743 | = has_gadt_match implics
|
| 720 | 744 | |
| 721 | 745 | ---------------
|
| 746 | +suppressItem :: ErrorItem -> Bool
|
|
| 747 | + -- See Note [Suppressing confusing errors]
|
|
| 748 | +suppressItem item
|
|
| 749 | + | Wanted <- ei_flavour item
|
|
| 750 | + , let orig = errorItemOrigin item
|
|
| 751 | + = isWantedSuperclassOrigin orig -- See (SCE1)
|
|
| 752 | + || isWantedWantedFunDepOrigin orig -- See (SCE2)
|
|
| 753 | + | otherwise
|
|
| 754 | + = False
|
|
| 755 | + |
|
| 722 | 756 | isSkolemTy :: TcLevel -> Type -> Bool
|
| 723 | 757 | -- The type is a skolem tyvar
|
| 724 | 758 | isSkolemTy tc_lvl ty
|
| ... | ... | @@ -743,7 +777,23 @@ If there are any other errors to report, at all, we want to suppress these. |
| 743 | 777 | |
| 744 | 778 | Which errors (only 1 case right now):
|
| 745 | 779 | |
| 746 | -1) Errors which arise from the interaction of two Wanted fun-dep constraints.
|
|
| 780 | +(SCE1) Superclasses of Wanteds. These are generated on in case they trigger functional
|
|
| 781 | + dependencies. If such a constraint is unsolved, then its "parent" constraint must
|
|
| 782 | + also be unsolved, and is much more informative to the user. Example (#26255):
|
|
| 783 | + class (MinVersion <= F era) => Era era where { ... }
|
|
| 784 | + f :: forall era. EraFamily era -> IO ()
|
|
| 785 | + f = ..blah... -- [W] Era era
|
|
| 786 | + Here we have simply omitted "Era era =>" from f's type. But we'll end up with
|
|
| 787 | + /two/ Wanted constraints:
|
|
| 788 | + [W] d1 : Era era
|
|
| 789 | + [W] d2 : MinVersion <= F era -- Superclass of d1
|
|
| 790 | + We definitely want to report d1 and not d2! Happily it's easy to filter out those
|
|
| 791 | + superclass-Wanteds, becuase their Origin betrays them.
|
|
| 792 | + |
|
| 793 | + See test T18851 for an example of how it is (just, barely) possible for the /only/
|
|
| 794 | + errors to be superclass-of-Wanted constraints.
|
|
| 795 | + |
|
| 796 | +(SCE2) Errors which arise from the interaction of two Wanted fun-dep constraints.
|
|
| 747 | 797 | Example:
|
| 748 | 798 | |
| 749 | 799 | class C a b | a -> b where
|
| ... | ... | @@ -786,7 +836,7 @@ they will remain unfilled, and might have been used to rewrite another constrain |
| 786 | 836 | |
| 787 | 837 | Currently, the constraints to ignore are:
|
| 788 | 838 | |
| 789 | -1) Constraints generated in order to unify associated type instance parameters
|
|
| 839 | +(CIG1) Constraints generated in order to unify associated type instance parameters
|
|
| 790 | 840 | with class parameters. Here are two illustrative examples:
|
| 791 | 841 | |
| 792 | 842 | class C (a :: k) where
|
| ... | ... | @@ -814,6 +864,9 @@ Currently, the constraints to ignore are: |
| 814 | 864 | |
| 815 | 865 | If there is any trouble, checkValidFamInst bleats, aborting compilation.
|
| 816 | 866 | |
| 867 | +(Note: Aug 25: this seems a rather tricky corner;
|
|
| 868 | + c.f. Note [Suppressing confusing errors])
|
|
| 869 | + |
|
| 817 | 870 | Note [Implementation of Unsatisfiable constraints]
|
| 818 | 871 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 819 | 872 | The Unsatisfiable constraint was introduced in GHC proposal #433 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0433-unsatisfiable.rst).
|
| ... | ... | @@ -2059,6 +2059,7 @@ isRigidTy ty |
| 2059 | 2059 | | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal
|
| 2060 | 2060 | | Just {} <- tcSplitAppTy_maybe ty = True
|
| 2061 | 2061 | | isForAllTy ty = True
|
| 2062 | + | Just {} <- isLitTy ty = True
|
|
| 2062 | 2063 | | otherwise = False
|
| 2063 | 2064 | |
| 2064 | 2065 | {-
|
| ... | ... | @@ -11,6 +11,11 @@ for specific guidance on migrating programs to this release. |
| 11 | 11 | Language
|
| 12 | 12 | ~~~~~~~~
|
| 13 | 13 | |
| 14 | +- Fix a bug introduced in GHC 9.10 where GHC would erroneously accept infix uses
|
|
| 15 | + of promoted data constructors without enabling :extension:`DataKinds`. As a
|
|
| 16 | + result, you may need to enable :extension:`DataKinds` in code that did not
|
|
| 17 | + previously require it.
|
|
| 18 | + |
|
| 14 | 19 | Compiler
|
| 15 | 20 | ~~~~~~~~
|
| 16 | 21 |
| ... | ... | @@ -1211,27 +1211,16 @@ INFO_TABLE_RET(stg_catch_retry_frame, CATCH_RETRY_FRAME, |
| 1211 | 1211 | gcptr trec, outer, arg;
|
| 1212 | 1212 | |
| 1213 | 1213 | trec = StgTSO_trec(CurrentTSO);
|
| 1214 | - if (running_alt_code != 1) {
|
|
| 1215 | - // When exiting the lhs code of catchRetry# lhs rhs, we need to cleanup
|
|
| 1216 | - // the nested transaction.
|
|
| 1217 | - // See Note [catchRetry# implementation]
|
|
| 1218 | - outer = StgTRecHeader_enclosing_trec(trec);
|
|
| 1219 | - (r) = ccall stmCommitNestedTransaction(MyCapability() "ptr", trec "ptr");
|
|
| 1220 | - if (r != 0) {
|
|
| 1221 | - // Succeeded in first branch
|
|
| 1222 | - StgTSO_trec(CurrentTSO) = outer;
|
|
| 1223 | - return (ret);
|
|
| 1224 | - } else {
|
|
| 1225 | - // Did not commit: abort and restart.
|
|
| 1226 | - StgTSO_trec(CurrentTSO) = outer;
|
|
| 1227 | - jump stg_abort();
|
|
| 1228 | - }
|
|
| 1229 | - }
|
|
| 1230 | - else {
|
|
| 1231 | - // nothing to do in the rhs code of catchRetry# lhs rhs, it's already
|
|
| 1232 | - // using the parent transaction (not a nested one).
|
|
| 1233 | - // See Note [catchRetry# implementation]
|
|
| 1234 | - return (ret);
|
|
| 1214 | + outer = StgTRecHeader_enclosing_trec(trec);
|
|
| 1215 | + (r) = ccall stmCommitNestedTransaction(MyCapability() "ptr", trec "ptr");
|
|
| 1216 | + if (r != 0) {
|
|
| 1217 | + // Succeeded (either first branch or second branch)
|
|
| 1218 | + StgTSO_trec(CurrentTSO) = outer;
|
|
| 1219 | + return (ret);
|
|
| 1220 | + } else {
|
|
| 1221 | + // Did not commit: abort and restart.
|
|
| 1222 | + StgTSO_trec(CurrentTSO) = outer;
|
|
| 1223 | + jump stg_abort();
|
|
| 1235 | 1224 | }
|
| 1236 | 1225 | }
|
| 1237 | 1226 | |
| ... | ... | @@ -1464,26 +1453,21 @@ retry_pop_stack: |
| 1464 | 1453 | outer = StgTRecHeader_enclosing_trec(trec);
|
| 1465 | 1454 | |
| 1466 | 1455 | if (frame_type == CATCH_RETRY_FRAME) {
|
| 1467 | - // The retry reaches a CATCH_RETRY_FRAME before the ATOMICALLY_FRAME
|
|
| 1468 | - |
|
| 1456 | + // The retry reaches a CATCH_RETRY_FRAME before the atomic frame
|
|
| 1457 | + ASSERT(outer != NO_TREC);
|
|
| 1458 | + // Abort the transaction attempting the current branch
|
|
| 1459 | + ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr");
|
|
| 1460 | + ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr");
|
|
| 1469 | 1461 | if (!StgCatchRetryFrame_running_alt_code(frame) != 0) {
|
| 1470 | - // Retrying in the lhs of catchRetry# lhs rhs, i.e. in a nested
|
|
| 1471 | - // transaction. See Note [catchRetry# implementation]
|
|
| 1472 | - |
|
| 1473 | - // check that we have a parent transaction
|
|
| 1474 | - ASSERT(outer != NO_TREC);
|
|
| 1475 | - |
|
| 1476 | - // Abort the nested transaction
|
|
| 1477 | - ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr");
|
|
| 1478 | - ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr");
|
|
| 1479 | - |
|
| 1480 | - // As we are retrying in the lhs code, we must now try the rhs code
|
|
| 1481 | - StgTSO_trec(CurrentTSO) = outer;
|
|
| 1462 | + // Retry in the first branch: try the alternative
|
|
| 1463 | + ("ptr" trec) = ccall stmStartTransaction(MyCapability() "ptr", outer "ptr");
|
|
| 1464 | + StgTSO_trec(CurrentTSO) = trec;
|
|
| 1482 | 1465 | StgCatchRetryFrame_running_alt_code(frame) = 1 :: CInt; // true;
|
| 1483 | 1466 | R1 = StgCatchRetryFrame_alt_code(frame);
|
| 1484 | 1467 | jump stg_ap_v_fast [R1];
|
| 1485 | 1468 | } else {
|
| 1486 | - // Retry in the rhs code: propagate the retry
|
|
| 1469 | + // Retry in the alternative code: propagate the retry
|
|
| 1470 | + StgTSO_trec(CurrentTSO) = outer;
|
|
| 1487 | 1471 | Sp = Sp + SIZEOF_StgCatchRetryFrame;
|
| 1488 | 1472 | goto retry_pop_stack;
|
| 1489 | 1473 | }
|
| ... | ... | @@ -1043,7 +1043,8 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, |
| 1043 | 1043 | }
|
| 1044 | 1044 | |
| 1045 | 1045 | case CATCH_STM_FRAME:
|
| 1046 | - // CATCH_STM frame within an atomically block: abort the
|
|
| 1046 | + case CATCH_RETRY_FRAME:
|
|
| 1047 | + // CATCH frames within an atomically block: abort the
|
|
| 1047 | 1048 | // inner transaction and continue. Eventually we will
|
| 1048 | 1049 | // hit the outer transaction that will get frozen (see
|
| 1049 | 1050 | // above).
|
| ... | ... | @@ -1055,40 +1056,14 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, |
| 1055 | 1056 | {
|
| 1056 | 1057 | StgTRecHeader *trec = tso -> trec;
|
| 1057 | 1058 | StgTRecHeader *outer = trec -> enclosing_trec;
|
| 1058 | - debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_STM frame");
|
|
| 1059 | + debugTraceCap(DEBUG_stm, cap,
|
|
| 1060 | + "found atomically block delivering async exception");
|
|
| 1059 | 1061 | stmAbortTransaction(cap, trec);
|
| 1060 | 1062 | stmFreeAbortedTRec(cap, trec);
|
| 1061 | 1063 | tso -> trec = outer;
|
| 1062 | 1064 | break;
|
| 1063 | 1065 | };
|
| 1064 | 1066 | |
| 1065 | - case CATCH_RETRY_FRAME:
|
|
| 1066 | - // CATCH_RETY frame within an atomically block: if we're executing
|
|
| 1067 | - // the lhs code, abort the inner transaction and continue; if we're
|
|
| 1068 | - // executing thr rhs, continue (no nested transaction to abort. See
|
|
| 1069 | - // Note [catchRetry# implementation]). Eventually we will hit the
|
|
| 1070 | - // outer transaction that will get frozen (see above).
|
|
| 1071 | - //
|
|
| 1072 | - // As for the CATCH_STM_FRAME case above, we do not care
|
|
| 1073 | - // whether the transaction is valid or not because its
|
|
| 1074 | - // possible validity cannot have caused the exception
|
|
| 1075 | - // and will not be visible after the abort.
|
|
| 1076 | - {
|
|
| 1077 | - if (!((StgCatchRetryFrame *)frame) -> running_alt_code) {
|
|
| 1078 | - debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_RETRY frame (lhs)");
|
|
| 1079 | - StgTRecHeader *trec = tso -> trec;
|
|
| 1080 | - StgTRecHeader *outer = trec -> enclosing_trec;
|
|
| 1081 | - stmAbortTransaction(cap, trec);
|
|
| 1082 | - stmFreeAbortedTRec(cap, trec);
|
|
| 1083 | - tso -> trec = outer;
|
|
| 1084 | - }
|
|
| 1085 | - else
|
|
| 1086 | - {
|
|
| 1087 | - debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_RETRY frame (rhs)");
|
|
| 1088 | - }
|
|
| 1089 | - break;
|
|
| 1090 | - };
|
|
| 1091 | - |
|
| 1092 | 1067 | default:
|
| 1093 | 1068 | // see Note [Update async masking state on unwind] in Schedule.c
|
| 1094 | 1069 | if (*frame == (W_)&stg_unmaskAsyncExceptionszh_ret_info) {
|
| ... | ... | @@ -1505,30 +1505,3 @@ void stmWriteTVar(Capability *cap, |
| 1505 | 1505 | }
|
| 1506 | 1506 | |
| 1507 | 1507 | /*......................................................................*/ |
| 1508 | - |
|
| 1509 | - |
|
| 1510 | - |
|
| 1511 | -/*
|
|
| 1512 | - |
|
| 1513 | -Note [catchRetry# implementation]
|
|
| 1514 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1515 | -catchRetry# creates a nested transaction for its lhs:
|
|
| 1516 | -- if the lhs transaction succeeds:
|
|
| 1517 | - - the lhs transaction is committed
|
|
| 1518 | - - its read-variables are merged with those of the parent transaction
|
|
| 1519 | - - the rhs code is ignored
|
|
| 1520 | -- if the lhs transaction retries:
|
|
| 1521 | - - the lhs transaction is aborted
|
|
| 1522 | - - its read-variables are merged with those of the parent transaction
|
|
| 1523 | - - the rhs code is executed directly in the parent transaction (see #26028).
|
|
| 1524 | - |
|
| 1525 | -So note that:
|
|
| 1526 | -- lhs code uses a nested transaction
|
|
| 1527 | -- rhs code doesn't use a nested transaction
|
|
| 1528 | - |
|
| 1529 | -We have to take which case we're in into account (using the running_alt_code
|
|
| 1530 | -field of the catchRetry frame) in catchRetry's entry code, in retry#
|
|
| 1531 | -implementation, and also when an async exception is received (to cleanup the
|
|
| 1532 | -right number of transactions).
|
|
| 1533 | - |
|
| 1534 | -*/ |
| 1 | -module Main where
|
|
| 2 | - |
|
| 3 | -import GHC.Conc
|
|
| 4 | - |
|
| 5 | -forever :: IO String
|
|
| 6 | -forever = delay 10 >> forever
|
|
| 7 | - |
|
| 8 | -terminates :: IO String
|
|
| 9 | -terminates = delay 1 >> pure "terminates"
|
|
| 10 | - |
|
| 11 | -delay s = threadDelay (1000000 * s)
|
|
| 12 | - |
|
| 13 | -async :: IO a -> IO (STM a)
|
|
| 14 | -async a = do
|
|
| 15 | - var <- atomically (newTVar Nothing)
|
|
| 16 | - forkIO (a >>= atomically . writeTVar var . Just)
|
|
| 17 | - pure (readTVar var >>= maybe retry pure)
|
|
| 18 | - |
|
| 19 | -main :: IO ()
|
|
| 20 | -main = do
|
|
| 21 | - x <- mapM async $ terminates : replicate 50000 forever
|
|
| 22 | - r <- atomically (foldr1 orElse x)
|
|
| 23 | - print r |
| 1 | -"terminates" |
| 1 | -test('T26028', only_ways(['threaded1']), compile_and_run, ['-O2']) |
| ... | ... | @@ -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 | +{-# LANGUAGE GHC2021 #-}
|
|
| 2 | +{-# LANGUAGE NoDataKinds #-}
|
|
| 3 | +module T26318 where
|
|
| 4 | + |
|
| 5 | +class C1 l
|
|
| 6 | +instance C1 (x : xs)
|
|
| 7 | + |
|
| 8 | +class C2 l
|
|
| 9 | +instance C2 (x ': xs)
|
|
| 10 | + |
|
| 11 | +class C3 l
|
|
| 12 | +instance C3 ((:) x xs)
|
|
| 13 | + |
|
| 14 | +class C4 l
|
|
| 15 | +instance C4 ('(:) x xs) |
| 1 | +T26318.hs:6:16: error: [GHC-68567]
|
|
| 2 | + Illegal type: ‘x : xs’
|
|
| 3 | + Suggested fix:
|
|
| 4 | + Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
|
|
| 5 | + |
|
| 6 | +T26318.hs:9:16: error: [GHC-68567]
|
|
| 7 | + Illegal type: ‘x ': xs’
|
|
| 8 | + Suggested fix:
|
|
| 9 | + Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
|
|
| 10 | + |
|
| 11 | +T26318.hs:12:14: error: [GHC-68567]
|
|
| 12 | + Illegal type: ‘(:)’
|
|
| 13 | + Suggested fix:
|
|
| 14 | + Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
|
|
| 15 | + |
|
| 16 | +T26318.hs:15:14: error: [GHC-68567]
|
|
| 17 | + Illegal type: ‘'(:)’
|
|
| 18 | + Suggested fix:
|
|
| 19 | + Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
|
|
| 20 | + |
| 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
|
| ... | ... | @@ -741,3 +741,6 @@ test('T25325', normal, compile_fail, ['']) |
| 741 | 741 | test('T25004', normal, compile_fail, [''])
|
| 742 | 742 | test('T25004k', normal, compile_fail, [''])
|
| 743 | 743 | test('T26004', normal, compile_fail, [''])
|
| 744 | +test('T26318', normal, compile_fail, [''])
|
|
| 745 | +test('T26255a', normal, compile_fail, [''])
|
|
| 746 | +test('T26255b', normal, compile_fail, ['']) |
| ... | ... | @@ -1105,6 +1105,20 @@ class DyLD { |
| 1105 | 1105 | if (/libHSghc-internal-\d+(\.\d+)*/i.test(soname)) {
|
| 1106 | 1106 | this.rts_init();
|
| 1107 | 1107 | delete this.rts_init;
|
| 1108 | + |
|
| 1109 | + // At this point the RTS symbols in linear memory are fixed
|
|
| 1110 | + // and constructors are run, especially the one in JSFFI.c
|
|
| 1111 | + // that does GHC RTS initialization for any code that links
|
|
| 1112 | + // JSFFI.o. Luckily no Haskell computation or gc has taken
|
|
| 1113 | + // place yet, so we must set keepCAFs=1 right now! Otherwise,
|
|
| 1114 | + // any BCO created by later TH splice or ghci expression may
|
|
| 1115 | + // refer to any CAF that's not reachable from GC roots (here
|
|
| 1116 | + // our only entry point is defaultServer) and the CAF could
|
|
| 1117 | + // have been GC'ed! (#26106)
|
|
| 1118 | + //
|
|
| 1119 | + // We call it here instead of in RTS C code, since we only
|
|
| 1120 | + // want keepCAFs=1 for ghci, not user code.
|
|
| 1121 | + this.exportFuncs.setKeepCAFs();
|
|
| 1108 | 1122 | }
|
| 1109 | 1123 | init();
|
| 1110 | 1124 | }
|