Sasha Bogicevic pushed to branch wip/21101 at Glasgow Haskell Compiler / GHC
Commits:
-
73dd146c
by Sasha Bogicevic at 2026-07-19T19:48:52+02:00
17 changed files:
- + changelog.d/21101
- compiler/GHC/Hs/Utils.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
- + 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
Changes:
| 1 | +section: compiler
|
|
| 2 | +synopsis: Improve error messages and hints for invalid record wildcards
|
|
| 3 | +description:
|
|
| 4 | + Record wildcard hints are now shown in more contexts and include
|
|
| 5 | + constructor arity; matching with ``..`` on a fieldless constructor
|
|
| 6 | + now produces a dedicated error message.
|
|
| 7 | +mrs: !8673
|
|
| 8 | +issues: #21101 |
| ... | ... | @@ -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)
|
| ... | ... | @@ -423,7 +423,12 @@ 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 | + -- NB: it's OK to use the dummy value of '0' for the constructor arity:
|
|
| 428 | + -- we only use this information for 'TcRnIllegalWildcardsInConstructor',
|
|
| 429 | + -- which is an error we don't emit when the constructor is unbound.
|
|
| 430 | + -- See GHC.Rename.Pat.rnHsRecFields.rn_dotdot.
|
|
| 431 | + |
|
| 427 | 432 | IAmTyCon {} -> failIllegalTyCon WL_ConLike qcon
|
| 428 | 433 | _ -> pprPanic "lookupConstructorInfo: not a ConLike" $
|
| 429 | 434 | 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,10 @@ 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 | + ; case conFieldInfo conInfo of
|
|
| 878 | + ConHasPositionalArgs nbArgs ->
|
|
| 879 | + addErr $ TcRnIllegalWildcardsInConstructor (toRecordFieldPart ctxt) con nbArgs
|
|
| 880 | + _ -> return ()
|
|
| 878 | 881 | ; let present_flds = mkOccSet $ map rdrNameOcc (getFieldRdrs flds)
|
| 879 | 882 | |
| 880 | 883 | -- 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
|
| ... | ... | @@ -818,17 +818,35 @@ data TcRnMessage where |
| 818 | 818 | TcRnNegativeNumTypeLiteral :: IntegralLit GhcRn -> TcRnMessage
|
| 819 | 819 | |
| 820 | 820 | {-| TcRnIllegalWildcardsInConstructor is an error that occurs whenever
|
| 821 | - the record wildcards '..' are used inside a constructor without labeled fields.
|
|
| 821 | + the record wildcards '..' are used with a constructor whose fields are
|
|
| 822 | + positional (unlabelled). The 'RecordFieldPart' field records whether
|
|
| 823 | + the wildcards occurred in a record construction (an expression) or in
|
|
| 824 | + a record pattern, so that the message and its suggested fixes can be
|
|
| 825 | + worded accordingly. Constructors with no fields at all do not trigger
|
|
| 826 | + this error: since GHC proposal 496 ("Nullary record wildcards"),
|
|
| 827 | + @C {..}@ is legal for nullary constructors.
|
|
| 828 | + Example(s):
|
|
| 822 | 829 | |
| 823 | - Examples(s): None
|
|
| 830 | + data D = D Int Bool
|
|
| 831 | + |
|
| 832 | + f :: D -> ()
|
|
| 833 | + f D{..} = () -- record pattern
|
|
| 834 | + |
|
| 835 | + g :: D
|
|
| 836 | + g = D{..} -- record construction
|
|
| 824 | 837 | |
| 825 | 838 | Test cases:
|
| 826 | 839 | rename/should_fail/T9815.hs
|
| 827 | 840 | rename/should_fail/T9815b.hs
|
| 828 | 841 | rename/should_fail/T9815ghci.hs
|
| 829 | 842 | rename/should_fail/T9815bghci.hs
|
| 843 | + rename/should_fail/T21101.hs
|
|
| 830 | 844 | -}
|
| 831 | - TcRnIllegalWildcardsInConstructor :: !Name -> TcRnMessage
|
|
| 845 | + TcRnIllegalWildcardsInConstructor
|
|
| 846 | + :: !RecordFieldPart -- ^ context in which the constructor application occurs
|
|
| 847 | + -> !Name -- ^ name of the constructor
|
|
| 848 | + -> !VisArity -- ^ arity of the constructor
|
|
| 849 | + -> TcRnMessage
|
|
| 832 | 850 | |
| 833 | 851 | {-| TcRnIgnoringAnnotations is a warning that occurs when the source code
|
| 834 | 852 | 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")
|
|
| 348 | 354 | |
| 349 | 355 | perhapsAsPat :: SDoc
|
| 350 | 356 | perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace"
|
| 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, [''])
|