Sasha Bogicevic pushed to branch wip/21101 at Glasgow Haskell Compiler / GHC
Commits:
-
d43a7b7a
by Brian McKenna at 2026-07-15T20:10:04+02:00
-
ede4b17b
by Ben Gamari at 2026-07-15T22:59:53-04:00
-
63b92a32
by Sasha Bogicevic at 2026-07-16T18:26:01+02:00
-
377dbd90
by Sasha Bogicevic at 2026-07-16T18:26:02+02:00
-
90d299eb
by Sasha Bogicevic at 2026-07-16T18:26:02+02:00
30 changed files:
- + changelog.d/T27360
- + changelog.d/T27456
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Types/GREInfo.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- libraries/base/changelog.md
- libraries/base/tests/T15349.stderr
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/tests/backtraces/T14532b.stdout
- testsuite/tests/codeGen/should_run/cgrun025.stderr
- testsuite/tests/exceptions/T26759.stderr
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- + testsuite/tests/pmcheck/should_compile/T27360.hs
- testsuite/tests/pmcheck/should_compile/all.T
- + testsuite/tests/rename/should_fail/T21101.hs
- + testsuite/tests/rename/should_fail/T21101.stderr
- testsuite/tests/rename/should_fail/T9815.stderr
- testsuite/tests/rename/should_fail/T9815b.stderr
- testsuite/tests/rename/should_fail/T9815bghci.stderr
- testsuite/tests/rename/should_fail/T9815ghci.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/runghc/T7859.stderr-mingw32
Changes:
| 1 | +section: compiler
|
|
| 2 | +issues: #27360
|
|
| 3 | +mrs: !16161
|
|
| 4 | +synopsis:
|
|
| 5 | + Recognise ``considerAccessible`` under ticks (``-g``, ``-finfo-table-map``, ``-fhpc`` etc)
|
|
| 6 | +description:
|
|
| 7 | + The pattern-match checker now properly recognises ``considerAccessible`` even
|
|
| 8 | + when it is surrounded by ticks (e.g. debug info ticks with ``-g``, with
|
|
| 9 | + ``-finfo-table-map``, etc). This ensures it works as advertised, suppressing
|
|
| 10 | + redundant pattern-match warnings, even when it occurs under a tick. |
| 1 | +section: base
|
|
| 2 | +issues: #27456
|
|
| 3 | +mrs: !16275
|
|
| 4 | +synopsis:
|
|
| 5 | + Show `ExceptionContext` in `displayExceptionAnnotation` implementation of `WhileHandling`
|
|
| 6 | +description:
|
|
| 7 | + In the past ``displayException`` (in terms of which ``WhileHandling``\'s ``displayExceptionAnnotation` is implemented) was changed to hide ``ExceptionContext``. This regressed the behavior of ``displayExceptionAnnotation`` from that which was originally specified. Restore the intended behavior of showing the ``ExceptionContext`` of the carried exception.
|
|
| 8 | + |
| ... | ... | @@ -1613,8 +1613,8 @@ hsConDeclsBinders in the following format: |
| 1613 | 1613 | with its record fields, in the form of a list of Int indices into...
|
| 1614 | 1614 | - IntMap FieldOcc, an IntMap of record fields.
|
| 1615 | 1615 | |
| 1616 | -(In actual fact, we use [(ConRdrName, Maybe [Located Int])], with Nothing indicating
|
|
| 1617 | -that the constructor has unlabelled fields: see Note [Local constructor info in the renamer]
|
|
| 1616 | +(In actual fact, we use [(ConRdrName, Either VisArity [Located Int])], with Left n indicating
|
|
| 1617 | +that the constructor has n unlabelled arguments: see Note [Local constructor info in the renamer]
|
|
| 1618 | 1618 | in GHC.Types.GREInfo.)
|
| 1619 | 1619 | |
| 1620 | 1620 | This allows us to do the following (see GHC.Rename.Names.getLocalNonValBinders.new_tc):
|
| ... | ... | @@ -1635,7 +1635,7 @@ Other relevant test cases: rnfail015. |
| 1635 | 1635 | -- See Note [Collecting record fields in data declarations].
|
| 1636 | 1636 | data LConsWithFields p =
|
| 1637 | 1637 | LConsWithFields
|
| 1638 | - { consWithFieldIndices :: [(LocatedA (IdP (GhcPass p)), Maybe [Located Int])]
|
|
| 1638 | + { consWithFieldIndices :: [(LocatedA (IdP (GhcPass p)), Either VisArity [Located Int])]
|
|
| 1639 | 1639 | , consFields :: IntMap (LFieldOcc (GhcPass p))
|
| 1640 | 1640 | }
|
| 1641 | 1641 | |
| ... | ... | @@ -1675,16 +1675,15 @@ hsConDeclsBinders cons = go emptyFieldIndices cons |
| 1675 | 1675 | LConsWithFields ns fs = go seen' rs
|
| 1676 | 1676 | |
| 1677 | 1677 | get_flds_h98 :: FieldIndices p -> HsConDeclH98Details (GhcPass p)
|
| 1678 | - -> (Maybe [Located Int], FieldIndices p)
|
|
| 1679 | - get_flds_h98 seen (RecCon _ flds) = first Just $ get_flds seen flds
|
|
| 1680 | - get_flds_h98 seen (PrefixCon _ []) = (Just [], seen)
|
|
| 1681 | - get_flds_h98 seen _ = (Nothing, seen)
|
|
| 1678 | + -> (Either VisArity [Located Int], FieldIndices p)
|
|
| 1679 | + get_flds_h98 seen (RecCon _ flds) = first Right $ get_flds seen flds
|
|
| 1680 | + get_flds_h98 seen (PrefixCon _ args) = (Left (length args), seen)
|
|
| 1681 | + get_flds_h98 seen (InfixCon {}) = (Left 2, seen)
|
|
| 1682 | 1682 | |
| 1683 | 1683 | get_flds_gadt :: FieldIndices p -> HsConDeclGADTDetails (GhcPass p)
|
| 1684 | - -> (Maybe [Located Int], FieldIndices p)
|
|
| 1685 | - get_flds_gadt seen (RecConGADT _ flds) = first Just $ get_flds seen flds
|
|
| 1686 | - get_flds_gadt seen (PrefixConGADT _ []) = (Just [], seen)
|
|
| 1687 | - get_flds_gadt seen _ = (Nothing, seen)
|
|
| 1684 | + -> (Either VisArity [Located Int], FieldIndices p)
|
|
| 1685 | + get_flds_gadt seen (RecConGADT _ flds) = first Right $ get_flds seen flds
|
|
| 1686 | + get_flds_gadt seen (PrefixConGADT _ args) = (Left (length args), seen)
|
|
| 1688 | 1687 | |
| 1689 | 1688 | get_flds :: FieldIndices p -> LocatedA [LHsConDeclRecField (GhcPass p)]
|
| 1690 | 1689 | -> ([Located Int], FieldIndices p)
|
| ... | ... | @@ -12,7 +12,8 @@ import GHC.Prelude |
| 12 | 12 | |
| 13 | 13 | import GHC.HsToCore.Pmc.Types
|
| 14 | 14 | import GHC.HsToCore.Pmc.Utils
|
| 15 | -import GHC.Core (Expr(Var,App))
|
|
| 15 | +import GHC.Core (CoreExpr, Expr(Var,App))
|
|
| 16 | +import GHC.Core.Utils (stripTicksTopE)
|
|
| 16 | 17 | import GHC.Data.FastString (unpackFS, lengthFS, mkFastStringShortText)
|
| 17 | 18 | import GHC.Driver.DynFlags
|
| 18 | 19 | import GHC.Hs
|
| ... | ... | @@ -474,24 +475,28 @@ desugarLocalBinds _binds = return GdEnd |
| 474 | 475 | -- | Desugar a pattern guard
|
| 475 | 476 | -- @pat <- e ==> let x = e; <guards for pat <- x>@
|
| 476 | 477 | desugarBind :: LPat GhcTc -> LHsExpr GhcTc -> DsM GrdDag
|
| 477 | -desugarBind p e = dsLExpr e >>= \case
|
|
| 478 | - Var y
|
|
| 479 | - | Nothing <- isDataConId_maybe y
|
|
| 480 | - -- RHS is a variable, so that will allow us to omit the let
|
|
| 481 | - -> desugarLPat y p
|
|
| 482 | - rhs -> do
|
|
| 483 | - (x, grds) <- desugarLPatV p
|
|
| 484 | - pure (PmLet x rhs `consGrdDag` grds)
|
|
| 478 | +desugarBind p e =
|
|
| 479 | + dsLExpr_stripTicks e >>= \case
|
|
| 480 | + Var y
|
|
| 481 | + | Nothing <- isDataConId_maybe y
|
|
| 482 | + -- RHS is a variable, so that will allow us to omit the let
|
|
| 483 | + -> desugarLPat y p
|
|
| 484 | + rhs -> do
|
|
| 485 | + (x, grds) <- desugarLPatV p
|
|
| 486 | + pure (PmLet x rhs `consGrdDag` grds)
|
|
| 485 | 487 | |
| 486 | 488 | -- | Desugar a boolean guard
|
| 487 | 489 | -- @e ==> let x = e; True <- x@
|
| 488 | 490 | desugarBoolGuard :: LHsExpr GhcTc -> DsM GrdDag
|
| 489 | 491 | desugarBoolGuard e
|
| 490 | - | isJust (isTrueLHsExpr e) = return GdEnd
|
|
| 492 | + | isJust (isTrueLHsExpr e) -- NB: looks through ticks
|
|
| 491 | 493 | -- The formal thing to do would be to generate (True <- True)
|
| 492 | 494 | -- but it is trivial to solve so instead we give back an empty
|
| 493 | 495 | -- GrdDag for efficiency
|
| 494 | - | otherwise = dsLExpr e >>= \case
|
|
| 496 | + = return GdEnd
|
|
| 497 | + |
|
| 498 | + | otherwise
|
|
| 499 | + = dsLExpr_stripTicks e >>= \case
|
|
| 495 | 500 | Var y
|
| 496 | 501 | | Nothing <- isDataConId_maybe y
|
| 497 | 502 | -- Omit the let by matching on y
|
| ... | ... | @@ -500,6 +505,19 @@ desugarBoolGuard e |
| 500 | 505 | x <- mkPmId boolTy
|
| 501 | 506 | pure $ sequencePmGrds [PmLet x rhs, vanillaConGrd x trueDataCon []]
|
| 502 | 507 | |
| 508 | +-- | Desugar an expression, stripping off top-level ticks from the resulting
|
|
| 509 | +-- Core expression.
|
|
| 510 | +--
|
|
| 511 | +-- This function is used instead of 'dsLExpr' when we are immediately going to
|
|
| 512 | +-- inspect the Core (as we do in e.g. 'desugarBoolGuard' or 'desugarBind') to
|
|
| 513 | +-- make sure we properly look through intervening ticks (fixing #27360).
|
|
| 514 | +--
|
|
| 515 | +-- It's not needed when all we do is stash the resulting 'CoreExpr' into a
|
|
| 516 | +-- 'GrdDag', as the rest of the machinery (such as 'GHC.HsToCore.Pmc.Solver.addCoreCt')
|
|
| 517 | +-- looks through ticks.
|
|
| 518 | +dsLExpr_stripTicks :: LHsExpr GhcTc -> DsM CoreExpr
|
|
| 519 | +dsLExpr_stripTicks e = stripTicksTopE (const True) <$> dsLExpr e
|
|
| 520 | + |
|
| 503 | 521 | {- Note [Field match order for RecCon]
|
| 504 | 522 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 505 | 523 | The order for RecCon field patterns actually determines evaluation order of
|
| ... | ... | @@ -423,7 +423,10 @@ lookupConstructorInfo qcon@(WithUserRdr _ con_name) |
| 423 | 423 | = do { info <- lookupGREInfo_GRE con_name
|
| 424 | 424 | ; case info of
|
| 425 | 425 | IAmConLike con_info -> return con_info
|
| 426 | - UnboundGRE -> return $ ConInfo (ConIsData []) ConHasPositionalArgs
|
|
| 426 | + UnboundGRE -> return $ ConInfo (ConIsData []) (ConHasPositionalArgs 0)
|
|
| 427 | + -- The arity is a dummy: an unbound constructor never reaches the
|
|
| 428 | + -- code that consults it (see the isUnboundName guard in
|
|
| 429 | + -- GHC.Rename.Pat.rn_dotdot).
|
|
| 427 | 430 | IAmTyCon {} -> failIllegalTyCon WL_ConLike qcon
|
| 428 | 431 | _ -> pprPanic "lookupConstructorInfo: not a ConLike" $
|
| 429 | 432 | vcat [ text "name:" <+> ppr con_name ]
|
| ... | ... | @@ -71,7 +71,7 @@ import GHC.Types.FieldLabel |
| 71 | 71 | import GHC.Types.Hint
|
| 72 | 72 | import GHC.Types.SourceFile
|
| 73 | 73 | import GHC.Types.SrcLoc as SrcLoc
|
| 74 | -import GHC.Types.Basic ( TyConFlavour (..), convImportLevel )
|
|
| 74 | +import GHC.Types.Basic (TyConFlavour (..), convImportLevel, VisArity)
|
|
| 75 | 75 | import GHC.Types.Id
|
| 76 | 76 | import GHC.Types.PkgQual
|
| 77 | 77 | import GHC.Types.GREInfo (ConInfo(..), ConFieldInfo (..), ConLikeInfo (ConIsData))
|
| ... | ... | @@ -875,15 +875,16 @@ getLocalNonValBinders fixity_env |
| 875 | 875 | --
|
| 876 | 876 | -- The information we needed was all set up for us:
|
| 877 | 877 | -- see Note [Collecting record fields in data declarations] in GHC.Hs.Utils.
|
| 878 | - mk_fld_env :: [(Name, Maybe [Located Int])] -> IntMap FieldLabel
|
|
| 878 | + mk_fld_env :: [(Name, Either VisArity [Located Int])] -> IntMap FieldLabel
|
|
| 879 | 879 | -> [(ConLikeName, ConInfo)]
|
| 880 | 880 | mk_fld_env names flds =
|
| 881 | 881 | [ (DataConName con, ConInfo (ConIsData (map fst names)) fld_info)
|
| 882 | - | (con, mb_fl_indxs) <- names
|
|
| 883 | - , let fld_info = case fmap (map ((flds IntMap.!) . unLoc)) mb_fl_indxs of
|
|
| 884 | - Nothing -> ConHasPositionalArgs
|
|
| 885 | - Just [] -> ConIsNullary
|
|
| 886 | - Just (fld:flds) -> ConHasRecordFields $ fld NE.:| flds ]
|
|
| 882 | + | (con, con_fl_indxs) <- names
|
|
| 883 | + , let fld_info = case fmap (map ((flds IntMap.!) . unLoc)) con_fl_indxs of
|
|
| 884 | + Left 0 -> ConIsNullary
|
|
| 885 | + Left arity -> ConHasPositionalArgs arity
|
|
| 886 | + Right [] -> ConIsNullary
|
|
| 887 | + Right (fld:flds) -> ConHasRecordFields $ fld NE.:| flds ]
|
|
| 887 | 888 | |
| 888 | 889 | new_assoc :: DuplicateRecordFields -> FieldSelectors -> LInstDecl GhcPs
|
| 889 | 890 | -> RnM [GlobalRdrElt]
|
| ... | ... | @@ -939,10 +940,10 @@ getLocalNonValBinders fixity_env |
| 939 | 940 | |
| 940 | 941 | -- Add errors if a constructor has a duplicate record field.
|
| 941 | 942 | add_dup_fld_errs :: IntMap FieldLabel
|
| 942 | - -> (Name, Maybe [Located Int])
|
|
| 943 | + -> (Name, Either VisArity [Located Int])
|
|
| 943 | 944 | -> IOEnv (Env TcGblEnv TcLclEnv) ()
|
| 944 | - add_dup_fld_errs all_flds (con, mb_con_flds)
|
|
| 945 | - | Just con_flds <- mb_con_flds
|
|
| 945 | + add_dup_fld_errs all_flds (con, con_flds_or_arity)
|
|
| 946 | + | Right con_flds <- con_flds_or_arity
|
|
| 946 | 947 | , let (_, dups) = removeDups (comparing unLoc) con_flds
|
| 947 | 948 | = for_ dups $ \ dup_flds ->
|
| 948 | 949 | -- Report the error at the location of the second occurrence
|
| ... | ... | @@ -874,7 +874,11 @@ rnHsRecFields ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }) |
| 874 | 874 | ; checkErr dd_flag (needFlagDotDot ctxt)
|
| 875 | 875 | ; (rdr_env, lcl_env) <- getRdrEnvs
|
| 876 | 876 | ; conInfo <- lookupConstructorInfo qcon
|
| 877 | - ; when (conFieldInfo conInfo == ConHasPositionalArgs) (addErr (TcRnIllegalWildcardsInConstructor con))
|
|
| 877 | + |
|
| 878 | + ; case conFieldInfo conInfo of
|
|
| 879 | + ConHasPositionalArgs nbArgs ->
|
|
| 880 | + addErr $ TcRnIllegalWildcardsInConstructor (toRecordFieldPart ctxt) con nbArgs
|
|
| 881 | + _ -> return ()
|
|
| 878 | 882 | ; let present_flds = mkOccSet $ map rdrNameOcc (getFieldRdrs flds)
|
| 879 | 883 | |
| 880 | 884 | -- For constructor uses (but not patterns)
|
| ... | ... | @@ -357,12 +357,12 @@ instance Diagnostic TcRnMessage where |
| 357 | 357 | -> mkSimpleDecorated $ vcat [text "Illegal view pattern: " <+> ppr pat]
|
| 358 | 358 | TcRnCharLiteralOutOfRange c
|
| 359 | 359 | -> mkSimpleDecorated $ text "character literal out of range: '\\" <> char c <> char '\''
|
| 360 | - TcRnIllegalWildcardsInConstructor con
|
|
| 360 | + TcRnIllegalWildcardsInConstructor ctx con _
|
|
| 361 | 361 | -> mkSimpleDecorated $
|
| 362 | - vcat [ text "Illegal `{..}' notation for constructor" <+> quotes (ppr con)
|
|
| 363 | - , nest 2 (text "Record wildcards may not be used for constructors with unlabelled fields.")
|
|
| 364 | - , nest 2 (text "Possible fix: Remove the `{..}' and add a match for each field of the constructor.")
|
|
| 365 | - ]
|
|
| 362 | + text "The data constructor" <+> quotes (ppr con)
|
|
| 363 | + <+> text "does not have named record fields, so the record"
|
|
| 364 | + <+> pprRecordFieldPart ctx
|
|
| 365 | + <+> quotes (ppr con <> text "{..}") <+> text "is invalid."
|
|
| 366 | 366 | TcRnIgnoringAnnotations anns
|
| 367 | 367 | -> mkSimpleDecorated $
|
| 368 | 368 | text "Ignoring ANN annotation" <> plural anns <> comma
|
| ... | ... | @@ -2791,8 +2791,12 @@ instance Diagnostic TcRnMessage where |
| 2791 | 2791 | -> [suggestExtension LangExt.ViewPatterns]
|
| 2792 | 2792 | TcRnCharLiteralOutOfRange{}
|
| 2793 | 2793 | -> noHints
|
| 2794 | - TcRnIllegalWildcardsInConstructor{}
|
|
| 2795 | - -> noHints
|
|
| 2794 | + TcRnIllegalWildcardsInConstructor ctx con arity
|
|
| 2795 | + -> case ctx of
|
|
| 2796 | + RecordFieldPattern{} -> [ SuggestEmptyRecordBraces con
|
|
| 2797 | + , SuggestExplicitConstructorArguments con arity
|
|
| 2798 | + ]
|
|
| 2799 | + _ -> [SuggestExplicitConstructorArguments con arity]
|
|
| 2796 | 2800 | TcRnIgnoringAnnotations{}
|
| 2797 | 2801 | -> noHints
|
| 2798 | 2802 | TcRnAnnotationInSafeHaskell
|
| ... | ... | @@ -817,17 +817,34 @@ data TcRnMessage where |
| 817 | 817 | TcRnNegativeNumTypeLiteral :: IntegralLit GhcRn -> TcRnMessage
|
| 818 | 818 | |
| 819 | 819 | {-| TcRnIllegalWildcardsInConstructor is an error that occurs whenever
|
| 820 | - the record wildcards '..' are used inside a constructor without labeled fields.
|
|
| 820 | + the record wildcards '..' are used with a constructor whose fields are
|
|
| 821 | + positional (unlabelled). The 'RecordFieldPart' field records whether
|
|
| 822 | + the wildcards occurred in a record construction (an expression) or in
|
|
| 823 | + a record pattern, so that the message and its suggested fixes can be
|
|
| 824 | + worded accordingly. Constructors with no fields at all do not trigger
|
|
| 825 | + this error: since GHC proposal 496 ("Nullary record wildcards"),
|
|
| 826 | + @C {..}@ is legal for nullary constructors.
|
|
| 827 | + The 'VisArity' field records the constructor's number of positional arguments
|
|
| 828 | + which the suggested fix mentions.
|
|
| 821 | 829 | |
| 822 | - Examples(s): None
|
|
| 830 | + Example(s):
|
|
| 831 | + |
|
| 832 | + data D = D Int Bool
|
|
| 833 | + |
|
| 834 | + f :: D -> ()
|
|
| 835 | + f D{..} = () -- record pattern
|
|
| 836 | + |
|
| 837 | + g :: D
|
|
| 838 | + g = D{..} -- record construction
|
|
| 823 | 839 | |
| 824 | 840 | Test cases:
|
| 825 | 841 | rename/should_fail/T9815.hs
|
| 826 | 842 | rename/should_fail/T9815b.hs
|
| 827 | 843 | rename/should_fail/T9815ghci.hs
|
| 828 | 844 | rename/should_fail/T9815bghci.hs
|
| 845 | + rename/should_fail/T21101.hs
|
|
| 829 | 846 | -}
|
| 830 | - TcRnIllegalWildcardsInConstructor :: !Name -> TcRnMessage
|
|
| 847 | + TcRnIllegalWildcardsInConstructor :: !RecordFieldPart -> !Name -> !VisArity -> TcRnMessage
|
|
| 831 | 848 | |
| 832 | 849 | {-| TcRnIgnoringAnnotations is a warning that occurs when the source code
|
| 833 | 850 | contains annotation pragmas but the platform in use does not support an
|
| ... | ... | @@ -244,14 +244,14 @@ instance NFData ConLikeInfo where |
| 244 | 244 | -- See Note [Local constructor info in the renamer]
|
| 245 | 245 | data ConFieldInfo
|
| 246 | 246 | = ConHasRecordFields (NonEmpty FieldLabel)
|
| 247 | - | ConHasPositionalArgs
|
|
| 247 | + | ConHasPositionalArgs !VisArity
|
|
| 248 | 248 | | ConIsNullary
|
| 249 | 249 | deriving stock Eq
|
| 250 | 250 | deriving Data
|
| 251 | 251 | |
| 252 | 252 | instance NFData ConFieldInfo where
|
| 253 | 253 | rnf ConIsNullary = ()
|
| 254 | - rnf ConHasPositionalArgs = ()
|
|
| 254 | + rnf (ConHasPositionalArgs arity) = rnf arity
|
|
| 255 | 255 | rnf (ConHasRecordFields flds) = rnf flds
|
| 256 | 256 | |
| 257 | 257 | mkConInfo :: ConLikeInfo -> VisArity -> [FieldLabel] -> ConInfo
|
| ... | ... | @@ -259,9 +259,9 @@ mkConInfo con_ty n flds = |
| 259 | 259 | ConInfo { conLikeInfo = con_ty
|
| 260 | 260 | , conFieldInfo = mkConFieldInfo n flds }
|
| 261 | 261 | |
| 262 | -mkConFieldInfo :: Arity -> [FieldLabel] -> ConFieldInfo
|
|
| 262 | +mkConFieldInfo :: VisArity -> [FieldLabel] -> ConFieldInfo
|
|
| 263 | 263 | mkConFieldInfo 0 _ = ConIsNullary
|
| 264 | -mkConFieldInfo _ fields = maybe ConHasPositionalArgs ConHasRecordFields
|
|
| 264 | +mkConFieldInfo arity fields = maybe (ConHasPositionalArgs arity) ConHasRecordFields
|
|
| 265 | 265 | $ NonEmpty.nonEmpty fields
|
| 266 | 266 | |
| 267 | 267 | conInfoFields :: ConInfo -> [FieldLabel]
|
| ... | ... | @@ -269,7 +269,7 @@ conInfoFields = conFieldInfoFields . conFieldInfo |
| 269 | 269 | |
| 270 | 270 | conFieldInfoFields :: ConFieldInfo -> [FieldLabel]
|
| 271 | 271 | conFieldInfoFields (ConHasRecordFields fields) = NonEmpty.toList fields
|
| 272 | -conFieldInfoFields ConHasPositionalArgs = []
|
|
| 272 | +conFieldInfoFields (ConHasPositionalArgs _) = []
|
|
| 273 | 273 | conFieldInfoFields ConIsNullary = []
|
| 274 | 274 | |
| 275 | 275 | instance Outputable ConInfo where
|
| ... | ... | @@ -284,7 +284,7 @@ instance Outputable ConLikeInfo where |
| 284 | 284 | |
| 285 | 285 | instance Outputable ConFieldInfo where
|
| 286 | 286 | ppr ConIsNullary = text "ConIsNullary"
|
| 287 | - ppr ConHasPositionalArgs = text "ConHasPositionalArgs"
|
|
| 287 | + ppr (ConHasPositionalArgs arity) = text "ConHasPositionalArgs" <+> braces (ppr arity)
|
|
| 288 | 288 | ppr (ConHasRecordFields fieldLabels) =
|
| 289 | 289 | text "ConHasRecordFields" <+> braces (ppr fieldLabels)
|
| 290 | 290 |
| ... | ... | @@ -45,7 +45,7 @@ import GHC.Types.InlinePragma (ActivationGhc) |
| 45 | 45 | import GHC.Types.Name (Name, NameSpace, OccName (occNameFS), isSymOcc, nameOccName)
|
| 46 | 46 | import GHC.Types.Name.Reader (RdrName (Unqual), ImpDeclSpec, GlobalRdrElt)
|
| 47 | 47 | import GHC.Types.SrcLoc (SrcSpan)
|
| 48 | -import GHC.Types.Basic (RuleName)
|
|
| 48 | +import GHC.Types.Basic (RuleName, VisArity)
|
|
| 49 | 49 | import GHC.Parser.Errors.Basic
|
| 50 | 50 | import GHC.Utils.Outputable
|
| 51 | 51 | import GHC.Data.FastString (fsLit)
|
| ... | ... | @@ -548,6 +548,23 @@ data GhcHint |
| 548 | 548 | | SuggestUpgradeForSemaphoreVersionMismatch !SemaphoreUpgradeTarget !Int
|
| 549 | 549 | -- ^ The 'Int' is the required protocol version.
|
| 550 | 550 | |
| 551 | + {-| Suggest replacing a record wildcard pattern @C {..}@ with @C {}@,
|
|
| 552 | + which matches a constructor without binding its fields.
|
|
| 553 | + |
|
| 554 | + Triggered by 'GHC.Tc.Errors.Types.TcRnIllegalWildcardsInConstructor'
|
|
| 555 | + in a record pattern.
|
|
| 556 | + -}
|
|
| 557 | + | SuggestEmptyRecordBraces !Name
|
|
| 558 | + |
|
| 559 | + {-| Suggest applying a constructor directly to its arguments instead
|
|
| 560 | + of record syntax, for constructors without labelled fields.
|
|
| 561 | + |
|
| 562 | + Triggered by 'GHC.Tc.Errors.Types.TcRnIllegalWildcardsInConstructor'
|
|
| 563 | + in a record construction and record patterns.
|
|
| 564 | + The 'VisArity' is the number of positional arguments of the constructor.
|
|
| 565 | + -}
|
|
| 566 | + | SuggestExplicitConstructorArguments !Name !VisArity
|
|
| 567 | + |
|
| 551 | 568 | -- | What the user should upgrade to resolve an @-jsem@ semaphore
|
| 552 | 569 | -- protocol version mismatch.
|
| 553 | 570 | data SemaphoreUpgradeTarget
|
| ... | ... | @@ -345,6 +345,12 @@ instance Outputable GhcHint where |
| 345 | 345 | text "The jobserver uses a newer semaphore protocol than this GHC."
|
| 346 | 346 | $$ (text "Upgrade GHC to a version that supports semaphore protocol v"
|
| 347 | 347 | <> int required <> text " to resolve this.")
|
| 348 | + SuggestEmptyRecordBraces con
|
|
| 349 | + -> text "Use" <+> quotes (ppr con <> text "{}") <+> text "instead,"
|
|
| 350 | + <+> text "which matches" <+> quotes (ppr con) <+> text "regardless of its fields"
|
|
| 351 | + SuggestExplicitConstructorArguments con nbArgs
|
|
| 352 | + -> text "Apply" <+> quotes (ppr con) <+> text "to its"
|
|
| 353 | + <+> speakNOf nbArgs (text "argument") <+> text "instead"
|
|
| 348 | 354 | |
| 349 | 355 | perhapsAsPat :: SDoc
|
| 350 | 356 | perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace"
|
| ... | ... | @@ -33,6 +33,7 @@ |
| 33 | 33 | * Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
|
| 34 | 34 | * Add a new module `System.IO.OS` with operations for obtaining operating-system handles (file descriptors, Windows handles). ([CLC proposal #369](https://github.com/haskell/core-libraries-committee/issues/369))
|
| 35 | 35 | * Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
|
| 36 | + * Show `ExceptionContext` in `displayExceptionAnnotation` implementation of `WhileHandling` ([GHC #27456](https://gitlab.haskell.org/ghc/ghc/-/issues/27456))
|
|
| 36 | 37 | * Hide implementation details when throwing exceptions in throw and throwSTM. ([CLC proposal #387](https://github.com/haskell/core-libraries-committee/issues/387))
|
| 37 | 38 | * Change `hIsReadable` and `hIsWritable` such that they always throw a respective exception when encountering a closed or semi-closed handle, not just in the case of a file handle. ([CLC proposal #371](github.com/haskell/core-libraries-committee/issues/371))
|
| 38 | 39 | * Annotate `onException` continuation with `WhileHandling`. ([CLC Proposal #397](https://github.com/haskell/core-libraries-committee/issues/397))
|
| 1 | -T15349: Uncaught exception ghc-internal:GHC.Internal.Control.Exception.Base.NonTermination:
|
|
| 1 | +T15349.exe: Uncaught exception ghc-internal:GHC.Internal.Control.Exception.Base.NonTermination:
|
|
| 2 | 2 | |
| 3 | 3 | <<loop>>
|
| 4 | 4 | |
| 5 | -While handling thread blocked indefinitely in an MVar operation
|
|
| 5 | +While handling ghc-internal:GHC.Internal.IO.Exception.BlockedIndefinitelyOnMVar:
|
|
| 6 | + |
|
|
| 7 | + | thread blocked indefinitely in an MVar operation
|
|
| 6 | 8 | |
| 7 | 9 | HasCallStack backtrace:
|
| 8 | - throwIO, called at libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Imp.hs:58:37 in ghc-internal:GHC.Internal.Control.Monad.ST.Imp
|
|
| 10 | + throwIO, called at libraries\ghc-internal\src\GHC\Internal\Control\Monad\ST\Imp.hs:59:37 in ghc-internal:GHC.Internal.Control.Monad.ST.Imp
|
|
| 9 | 11 |
| ... | ... | @@ -84,7 +84,7 @@ data WhileHandling = WhileHandling SomeException deriving Show |
| 84 | 84 | |
| 85 | 85 | instance ExceptionAnnotation WhileHandling where
|
| 86 | 86 | displayExceptionAnnotation (WhileHandling e) =
|
| 87 | - "While handling " ++ case lines $ displayException e of
|
|
| 87 | + "While handling " ++ case lines $ displayExceptionWithInfo e of
|
|
| 88 | 88 | [] -> ""
|
| 89 | 89 | (l1:ls) ->
|
| 90 | 90 | -- Indent lines forward.
|
| ... | ... | @@ -2,7 +2,14 @@ ghc-internal:GHC.Internal.Exception.ErrorCall: |
| 2 | 2 | |
| 3 | 3 | Error in Exception Handler
|
| 4 | 4 | |
| 5 | -While handling Main Error
|
|
| 5 | +While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 6 | + |
|
|
| 7 | + | Main Error
|
|
| 8 | + |
|
|
| 9 | + | My custom Backtraces:
|
|
| 10 | + | HasCallStack backtrace:
|
|
| 11 | + | throwIO, called at T14532b.hs:32:6 in main:Main
|
|
| 12 | + |
|
|
| 6 | 13 | |
| 7 | 14 | My custom Backtraces:
|
| 8 | 15 | HasCallStack backtrace:
|
| ... | ... | @@ -13,7 +20,14 @@ ghc-internal:GHC.Internal.Exception.ErrorCall: |
| 13 | 20 | |
| 14 | 21 | Error in Exception Handler
|
| 15 | 22 | |
| 16 | -While handling Main Error
|
|
| 23 | +While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 24 | + |
|
|
| 25 | + | Main Error
|
|
| 26 | + |
|
|
| 27 | + | My custom Backtraces:
|
|
| 28 | + | HasCallStack backtrace:
|
|
| 29 | + | error, called at T14532b.hs:41:6 in main:Main
|
|
| 30 | + |
|
|
| 17 | 31 | |
| 18 | 32 | My custom Backtraces:
|
| 19 | 33 | HasCallStack backtrace:
|
| 1 | -"cgrun025"
|
|
| 1 | +"cgrun025.exe"
|
|
| 2 | 2 | ["cgrun025.hs"]
|
| 3 | 3 | GOT PATH
|
| 4 | 4 | {-# LANGUAGE ScopedTypeVariables #-}
|
| ... | ... | @@ -27,11 +27,16 @@ main = do |
| 27 | 27 | trace "hello, trace" $
|
| 28 | 28 | catch (getEnv "__WURBLE__" >> return ()) (\ (e :: SomeException) -> error "hello, error")
|
| 29 | 29 | hello, trace
|
| 30 | -cgrun025: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 30 | +cgrun025.exe: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 31 | 31 | |
| 32 | 32 | hello, error
|
| 33 | 33 | |
| 34 | -While handling __WURBLE__: getEnv: does not exist (no environment variable)
|
|
| 34 | +While handling ghc-internal:GHC.Internal.IO.Exception.IOException:
|
|
| 35 | + |
|
|
| 36 | + | __WURBLE__: getEnv: does not exist (no environment variable)
|
|
| 37 | + |
|
|
| 38 | + | HasCallStack backtrace:
|
|
| 39 | + | ioException, called at libraries\ghc-internal\src\GHC\Internal\System\Environment.hs:204:26 in ghc-internal:GHC.Internal.System.Environment
|
|
| 35 | 40 | |
| 36 | 41 | HasCallStack backtrace:
|
| 37 | 42 | error, called at cgrun025.hs:25:75 in main:Main
|
| 1 | -T26759: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 1 | +T26759.exe: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 2 | 2 | |
| 3 | 3 | cleanup failure
|
| 4 | 4 | |
| 5 | -While handling outer failure
|
|
| 5 | +While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 6 | + |
|
|
| 7 | + | outer failure
|
|
| 8 | + |
|
|
| 9 | + | HasCallStack backtrace:
|
|
| 10 | + | throwIO, called at T26759.hs:6:21 in main:Main
|
|
| 6 | 11 | |
| 7 | 12 | HasCallStack backtrace:
|
| 8 | 13 | throwIO, called at T26759.hs:7:22 in main:Main
|
| 1 | -<interactive>: Uncaught exception ghc-9.13-inplace:GHC.Utils.Panic.GhcException:
|
|
| 1 | +<interactive>: Uncaught exception ghc-10.1-inplace:GHC.Utils.Panic.GhcException:
|
|
| 2 | 2 | |
| 3 | 3 | IO error: "Abcde" does not exist
|
| 4 | 4 | |
| 5 | -While handling IO error: "Abcde" does not exist
|
|
| 5 | +While handling ghc-10.1-inplace:GHC.Utils.Panic.GhcException:
|
|
| 6 | + |
|
|
| 7 | + | IO error: "Abcde" does not exist
|
|
| 6 | 8 | |
| 7 | 9 | HasCallStack backtrace:
|
| 8 | - throwIO, called at compiler/GHC/Utils/Error.hs:512:19 in ghc-9.13-inplace:GHC.Utils.Error
|
|
| 10 | + throwIO, called at compiler\GHC\Utils\Error.hs:499:19 in ghc-10.1-inplace:GHC.Utils.Error
|
|
| 9 | 11 | |
| 10 | 12 | 1 |
| 1 | -mdofail006: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.FixIOException:
|
|
| 1 | +mdofail006.exe: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.FixIOException:
|
|
| 2 | 2 | |
| 3 | 3 | cyclic evaluation in fixIO
|
| 4 | 4 | |
| 5 | -While handling thread blocked indefinitely in an MVar operation
|
|
| 5 | +While handling ghc-internal:GHC.Internal.IO.Exception.BlockedIndefinitelyOnMVar:
|
|
| 6 | + |
|
|
| 7 | + | thread blocked indefinitely in an MVar operation
|
|
| 6 | 8 | |
| 7 | 9 | HasCallStack backtrace:
|
| 8 | - throwIO, called at libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs:167:37 in ghc-internal:GHC.Internal.Control.Monad.Fix
|
|
| 10 | + throwIO, called at libraries\ghc-internal\src\GHC\Internal\Control\Monad\Fix.hs:169:37 in ghc-internal:GHC.Internal.Control.Monad.Fix
|
|
| 9 | 11 |
| 1 | +module T27360 where
|
|
| 2 | + |
|
| 3 | +import GHC.Exts
|
|
| 4 | + |
|
| 5 | +f :: ()
|
|
| 6 | +f | False, considerAccessible = ()
|
|
| 7 | + | otherwise = ()
|
|
| 8 | + |
|
| 9 | +g :: ()
|
|
| 10 | +g | False, True <- considerAccessible = ()
|
|
| 11 | + | otherwise = () |
| ... | ... | @@ -182,3 +182,4 @@ test('T24845', [], compile, [overlapping_incomplete]) |
| 182 | 182 | test('T22652', [], compile, [overlapping_incomplete])
|
| 183 | 183 | test('T22652a', [], compile, [overlapping_incomplete])
|
| 184 | 184 | test('T24867', [], compile_fail, [overlapping_incomplete])
|
| 185 | +test('T27360', normal, compile, [overlapping_incomplete + '-g3']) |
| 1 | +{-# LANGUAGE RecordWildCards #-}
|
|
| 2 | +module T21101 where
|
|
| 3 | + |
|
| 4 | +data D = D Int Bool
|
|
| 5 | + |
|
| 6 | +f :: D -> ()
|
|
| 7 | +f D{..} = () |
| 1 | +T21101.hs:7:3: error: [GHC-47217]
|
|
| 2 | + The data constructor ‘D’ does not have named record fields, so the record pattern ‘D{..}’ is invalid.
|
|
| 3 | + Suggested fixes:
|
|
| 4 | + • Use ‘D{}’ instead, which matches ‘D’ regardless of its fields
|
|
| 5 | + • Apply ‘D’ to its two arguments instead
|
|
| 6 | + |
| 1 | - |
|
| 2 | 1 | T9815.hs:6:13: error: [GHC-47217]
|
| 3 | - Illegal `{..}' notation for constructor ‘N’
|
|
| 4 | - Record wildcards may not be used for constructors with unlabelled fields.
|
|
| 5 | - Possible fix: Remove the `{..}' and add a match for each field of the constructor. |
|
| 2 | + The data constructor ‘N’ does not have named record fields, so the record construction ‘N{..}’ is invalid.
|
|
| 3 | + Suggested fix: Apply ‘N’ to its one argument instead
|
|
| 4 | + |
| 1 | - |
|
| 2 | 1 | T9815.hs:6:13: error: [GHC-47217]
|
| 3 | - Illegal `{..}' notation for constructor ‘N’
|
|
| 4 | - Record wildcards may not be used for constructors with unlabelled fields.
|
|
| 5 | - Possible fix: Remove the `{..}' and add a match for each field of the constructor. |
|
| 2 | + The data constructor ‘N’ does not have named record fields, so the record construction ‘N{..}’ is invalid.
|
|
| 3 | + Suggested fix: Apply ‘N’ to its one argument instead
|
|
| 4 | + |
| 1 | +<interactive>:5:7: error: [GHC-47217]
|
|
| 2 | + The data constructor ‘Arg’ does not have named record fields, so the record construction ‘Arg{..}’ is invalid.
|
|
| 3 | + Suggested fix: Apply ‘Arg’ to its two arguments instead
|
|
| 1 | 4 | |
| 2 | -<interactive>:5:7: [GHC-47217]
|
|
| 3 | - Illegal `{..}' notation for constructor ‘Arg’
|
|
| 4 | - Record wildcards may not be used for constructors with unlabelled fields.
|
|
| 5 | - Possible fix: Remove the `{..}' and add a match for each field of the constructor. |
| 1 | +<interactive>:3:7: error: [GHC-47217]
|
|
| 2 | + The data constructor ‘Data.Semigroup.Arg’ does not have named record fields, so the record construction ‘Data.Semigroup.Arg{..}’ is invalid.
|
|
| 3 | + Suggested fix:
|
|
| 4 | + Apply ‘Data.Semigroup.Arg’ to its two arguments instead
|
|
| 1 | 5 | |
| 2 | -<interactive>:3:7: [GHC-47217]
|
|
| 3 | - Illegal `{..}' notation for constructor ‘Data.Semigroup.Arg’
|
|
| 4 | - Record wildcards may not be used for constructors with unlabelled fields.
|
|
| 5 | - Possible fix: Remove the `{..}' and add a match for each field of the constructor. |
| ... | ... | @@ -186,6 +186,7 @@ test('T18138', normal, compile_fail, ['']) |
| 186 | 186 | test('T20147', normal, compile_fail, [''])
|
| 187 | 187 | test('RnEmptyStatementGroup1', normal, compile_fail, [''])
|
| 188 | 188 | test('RnImplicitBindInMdoNotation', normal, compile_fail, [''])
|
| 189 | +test('T21101', normal, compile_fail, [''])
|
|
| 189 | 190 | test('T21605a', normal, compile_fail, [''])
|
| 190 | 191 | test('T21605b', normal, compile_fail, [''])
|
| 191 | 192 | test('T21605c', normal, compile_fail, [''])
|
| ... | ... | @@ -2,7 +2,12 @@ runghc-9.13.20241015.exe: Uncaught exception ghc-internal:GHC.Internal.IO.Except |
| 2 | 2 | |
| 3 | 3 | defer-type-errors: rawSystem: does not exist (No such file or directory)
|
| 4 | 4 | |
| 5 | -While handling rawSystem: does not exist (No such file or directory)
|
|
| 5 | +While handling ghc-internal:GHC.Internal.IO.Exception.IOException:
|
|
| 6 | + |
|
|
| 7 | + | rawSystem: does not exist (No such file or directory)
|
|
| 8 | + |
|
|
| 9 | + | HasCallStack backtrace:
|
|
| 10 | + | ioError, called at libraries/ghc-internal/src/GHC/Internal/Foreign/C/Error.hs:<line>:<column> in <package-id>:GHC.Internal.Foreign.C.Error
|
|
| 6 | 11 | |
| 7 | 12 | HasCallStack backtrace:
|
| 8 | 13 | ioError, called at libraries\process\System\Process\Common.hs:239:16 in process-1.6.25.0-inplace:System.Process.Common
|