Sasha Bogicevic pushed to branch wip/21101 at Glasgow Haskell Compiler / GHC

Commits:

14 changed files:

Changes:

  • compiler/GHC/Hs/Utils.hs
    ... ... @@ -1589,8 +1589,8 @@ hsConDeclsBinders in the following format:
    1589 1589
         with its record fields, in the form of a list of Int indices into...
    
    1590 1590
       - IntMap FieldOcc, an IntMap of record fields.
    
    1591 1591
     
    
    1592
    -(In actual fact, we use [(ConRdrName, Maybe [Located Int])], with Nothing indicating
    
    1593
    -that the constructor has unlabelled fields: see Note [Local constructor info in the renamer]
    
    1592
    +(In actual fact, we use [(ConRdrName, Either VisArity [Located Int])], with Left n indicating
    
    1593
    +that the constructor has n unlabelled arguments: see Note [Local constructor info in the renamer]
    
    1594 1594
     in GHC.Types.GREInfo.)
    
    1595 1595
     
    
    1596 1596
     This allows us to do the following (see GHC.Rename.Names.getLocalNonValBinders.new_tc):
    
    ... ... @@ -1611,7 +1611,7 @@ Other relevant test cases: rnfail015.
    1611 1611
     -- See Note [Collecting record fields in data declarations].
    
    1612 1612
     data LConsWithFields p =
    
    1613 1613
       LConsWithFields
    
    1614
    -    { consWithFieldIndices :: [(LocatedA (IdP (GhcPass p)), Maybe [Located Int])]
    
    1614
    +    { consWithFieldIndices :: [(LocatedA (IdP (GhcPass p)), Either VisArity [Located Int])]
    
    1615 1615
         , consFields :: IntMap (LFieldOcc (GhcPass p))
    
    1616 1616
         }
    
    1617 1617
     
    
    ... ... @@ -1651,16 +1651,15 @@ hsConDeclsBinders cons = go emptyFieldIndices cons
    1651 1651
                     LConsWithFields ns fs = go seen' rs
    
    1652 1652
     
    
    1653 1653
         get_flds_h98 :: FieldIndices p -> HsConDeclH98Details (GhcPass p)
    
    1654
    -                 -> (Maybe [Located Int], FieldIndices p)
    
    1655
    -    get_flds_h98 seen (RecCon _ flds) = first Just $ get_flds seen flds
    
    1656
    -    get_flds_h98 seen (PrefixCon _ []) = (Just [], seen)
    
    1657
    -    get_flds_h98 seen _ = (Nothing, seen)
    
    1654
    +                 -> (Either VisArity [Located Int], FieldIndices p)
    
    1655
    +    get_flds_h98 seen (RecCon _ flds) = first Right $ get_flds seen flds
    
    1656
    +    get_flds_h98 seen (PrefixCon _ args) = (Left (length args), seen)
    
    1657
    +    get_flds_h98 seen (InfixCon {}) = (Left 2, seen)
    
    1658 1658
     
    
    1659 1659
         get_flds_gadt :: FieldIndices p -> HsConDeclGADTDetails (GhcPass p)
    
    1660
    -                  -> (Maybe [Located Int], FieldIndices p)
    
    1661
    -    get_flds_gadt seen (RecConGADT _ flds) = first Just $ get_flds seen flds
    
    1662
    -    get_flds_gadt seen (PrefixConGADT _ []) = (Just [], seen)
    
    1663
    -    get_flds_gadt seen _ = (Nothing, seen)
    
    1660
    +                  -> (Either VisArity [Located Int], FieldIndices p)
    
    1661
    +    get_flds_gadt seen (RecConGADT _ flds) = first Right $ get_flds seen flds
    
    1662
    +    get_flds_gadt seen (PrefixConGADT _ args) = (Left (length args), seen)
    
    1664 1663
     
    
    1665 1664
         get_flds :: FieldIndices p -> LocatedA [LHsConDeclRecField (GhcPass p)]
    
    1666 1665
                  -> ([Located Int], FieldIndices p)
    

  • compiler/GHC/Rename/Env.hs
    ... ... @@ -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 ]
    

  • compiler/GHC/Rename/Names.hs
    ... ... @@ -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
    

  • compiler/GHC/Rename/Pat.hs
    ... ... @@ -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 (toRecordFieldPart ctxt) 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)
    

  • compiler/GHC/Tc/Errors/Ppr.hs
    ... ... @@ -357,7 +357,7 @@ 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 ctx con
    
    360
    +    TcRnIllegalWildcardsInConstructor ctx con _
    
    361 361
           -> mkSimpleDecorated $
    
    362 362
                text "The data constructor" <+> quotes (ppr con)
    
    363 363
                  <+> text "does not have named record fields, so the record"
    
    ... ... @@ -2791,10 +2791,12 @@ instance Diagnostic TcRnMessage where
    2791 2791
           -> [suggestExtension LangExt.ViewPatterns]
    
    2792 2792
         TcRnCharLiteralOutOfRange{}
    
    2793 2793
           -> noHints
    
    2794
    -    TcRnIllegalWildcardsInConstructor ctx con
    
    2794
    +    TcRnIllegalWildcardsInConstructor ctx con arity
    
    2795 2795
           -> case ctx of
    
    2796
    -           RecordFieldPattern{} -> [SuggestEmptyRecordBraces con]
    
    2797
    -           _                    -> [SuggestExplicitConstructorArguments con]
    
    2796
    +           RecordFieldPattern{} -> [ SuggestEmptyRecordBraces con
    
    2797
    +                                   , SuggestExplicitConstructorArguments con arity
    
    2798
    +                                   ]
    
    2799
    +           _                    -> [SuggestExplicitConstructorArguments con arity]
    
    2798 2800
         TcRnIgnoringAnnotations{}
    
    2799 2801
           -> noHints
    
    2800 2802
         TcRnAnnotationInSafeHaskell
    

  • compiler/GHC/Tc/Errors/Types.hs
    ... ... @@ -824,6 +824,8 @@ data TcRnMessage where
    824 824
           worded accordingly. Constructors with no fields at all do not trigger
    
    825 825
           this error: since GHC proposal 496 ("Nullary record wildcards"),
    
    826 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.
    
    827 829
     
    
    828 830
           Example(s):
    
    829 831
     
    
    ... ... @@ -842,7 +844,7 @@ data TcRnMessage where
    842 844
            rename/should_fail/T9815bghci.hs
    
    843 845
            rename/should_fail/T21101.hs
    
    844 846
       -}
    
    845
    -  TcRnIllegalWildcardsInConstructor :: !RecordFieldPart -> !Name -> TcRnMessage
    
    847
    +  TcRnIllegalWildcardsInConstructor :: !RecordFieldPart -> !Name -> !VisArity -> TcRnMessage
    
    846 848
     
    
    847 849
       {-| TcRnIgnoringAnnotations is a warning that occurs when the source code
    
    848 850
           contains annotation pragmas but the platform in use does not support an
    

  • compiler/GHC/Types/GREInfo.hs
    ... ... @@ -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
     
    

  • compiler/GHC/Types/Hint.hs
    ... ... @@ -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)
    
    ... ... @@ -560,9 +560,10 @@ data GhcHint
    560 560
           of record syntax, for constructors without labelled fields.
    
    561 561
     
    
    562 562
           Triggered by 'GHC.Tc.Errors.Types.TcRnIllegalWildcardsInConstructor'
    
    563
    -      in a record construction.
    
    563
    +      in a record construction and record patterns.
    
    564
    +      The 'VisArity' is the number of positional arguments of the constructor.
    
    564 565
       -}
    
    565
    -  | SuggestExplicitConstructorArguments !Name
    
    566
    +  | SuggestExplicitConstructorArguments !Name !VisArity
    
    566 567
     
    
    567 568
     -- | What the user should upgrade to resolve an @-jsem@ semaphore
    
    568 569
     --   protocol version mismatch.
    

  • compiler/GHC/Types/Hint/Ppr.hs
    ... ... @@ -348,8 +348,9 @@ instance Outputable GhcHint where
    348 348
         SuggestEmptyRecordBraces con
    
    349 349
           -> text "Use" <+> quotes (ppr con <> text "{}") <+> text "instead,"
    
    350 350
              <+> text "which matches" <+> quotes (ppr con) <+> text "regardless of its fields"
    
    351
    -    SuggestExplicitConstructorArguments con
    
    352
    -      -> text "Apply" <+> quotes (ppr con) <+> text "to its arguments instead"
    
    351
    +    SuggestExplicitConstructorArguments con nbArgs
    
    352
    +      -> text "Apply" <+> quotes (ppr con) <+> text "to its"
    
    353
    +         <+> speakNOf nbArgs (text "argument") <+> text "instead"
    
    353 354
     
    
    354 355
     perhapsAsPat :: SDoc
    
    355 356
     perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace"
    

  • testsuite/tests/rename/should_fail/T21101.stderr
    1 1
     T21101.hs:7:3: error: [GHC-47217]
    
    2 2
         The data constructor ‘D’ does not have named record fields, so the record pattern ‘D{..}’ is invalid.
    
    3
    -    Suggested fix:
    
    4
    -      Use ‘D{}’ instead, which matches ‘D’ regardless of its fields
    
    3
    +    Suggested fixes:
    
    4
    +      • Use ‘D{}’ instead, which matches ‘D’ regardless of its fields
    
    5
    +      • Apply ‘D’ to its two arguments instead
    
    5 6
     

  • testsuite/tests/rename/should_fail/T9815.stderr
    1 1
     T9815.hs:6:13: error: [GHC-47217]
    
    2 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 arguments instead
    
    3
    +    Suggested fix: Apply ‘N’ to its one argument instead
    
    4 4
     

  • testsuite/tests/rename/should_fail/T9815b.stderr
    1 1
     T9815.hs:6:13: error: [GHC-47217]
    
    2 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 arguments instead
    
    3
    +    Suggested fix: Apply ‘N’ to its one argument instead
    
    4 4
     

  • testsuite/tests/rename/should_fail/T9815bghci.stderr
    1 1
     <interactive>:5:7: error: [GHC-47217]
    
    2 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 arguments instead
    
    3
    +    Suggested fix: Apply ‘Arg’ to its two arguments instead
    
    4 4
     

  • testsuite/tests/rename/should_fail/T9815ghci.stderr
    1 1
     <interactive>:3:7: error: [GHC-47217]
    
    2 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: Apply ‘Data.Semigroup.Arg’ to its arguments instead
    
    3
    +    Suggested fix:
    
    4
    +      Apply ‘Data.Semigroup.Arg’ to its two arguments instead
    
    4 5