Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

29 changed files:

Changes:

  • compiler/GHC/Core/ConLike.hs
    ... ... @@ -26,6 +26,8 @@ module GHC.Core.ConLike (
    26 26
             , conLikeFieldType
    
    27 27
             , conLikeIsInfix
    
    28 28
             , conLikeHasBuilder
    
    29
    +
    
    30
    +        , isExistentialRecordField
    
    29 31
         ) where
    
    30 32
     
    
    31 33
     import GHC.Prelude
    
    ... ... @@ -35,7 +37,7 @@ import GHC.Core.Multiplicity
    35 37
     import GHC.Core.PatSyn
    
    36 38
     import GHC.Core.TyCo.Rep (Type, ThetaType)
    
    37 39
     import GHC.Core.TyCon (tyConDataCons)
    
    38
    -import GHC.Core.Type(mkTyConApp)
    
    40
    +import GHC.Core.Type(mkTyConApp, tyCoVarsOfType)
    
    39 41
     import GHC.Types.Unique
    
    40 42
     import GHC.Types.Name
    
    41 43
     import GHC.Types.Name.Reader
    
    ... ... @@ -43,6 +45,7 @@ import GHC.Types.Basic
    43 45
     
    
    44 46
     import GHC.Types.GREInfo
    
    45 47
     import GHC.Types.Var
    
    48
    +import GHC.Types.Var.Set
    
    46 49
     import GHC.Utils.Misc
    
    47 50
     import GHC.Utils.Outputable
    
    48 51
     
    
    ... ... @@ -239,3 +242,23 @@ conLikeFieldType (RealDataCon dc) label = dataConFieldType dc label
    239 242
     conLikeIsInfix :: ConLike -> Bool
    
    240 243
     conLikeIsInfix (RealDataCon dc) = dataConIsInfix dc
    
    241 244
     conLikeIsInfix (PatSynCon ps)   = patSynIsInfix  ps
    
    245
    +
    
    246
    +-- | Is this record field a naughty record field due to the presence of
    
    247
    +-- existential type variables?
    
    248
    +--
    
    249
    +-- Different from 'isNaughtyRecordSelector' because the latter is also true
    
    250
    +-- in the presence of @-XNoFieldSelectors@.
    
    251
    +--
    
    252
    +-- See Note [Naughty record selectors] in GHC.Tc.TyCl.Utils.
    
    253
    +isExistentialRecordField :: Type -> ConLike -> Bool
    
    254
    +isExistentialRecordField field_ty con =
    
    255
    +  case con of
    
    256
    +    RealDataCon {} -> not $ field_ty_tvs `subVarSet` res_ty_tvs
    
    257
    +    PatSynCon {}   -> not $ field_ty_tvs `subVarSet` mkVarSet univ_tvs
    
    258
    +       -- In the PatSynCon case, the selector type is (data_ty -> field_ty), but
    
    259
    +       -- fvs(data_ty) are all universals (see Note [Pattern synonym result type] in
    
    260
    +       -- GHC.Core.PatSyn, so no need to check them.
    
    261
    +  where
    
    262
    +    field_ty_tvs = tyCoVarsOfType field_ty
    
    263
    +    res_ty_tvs   = tyCoVarsOfType data_ty
    
    264
    +    (univ_tvs, _, _, _, _, _, data_ty) = conLikeFullSig con

  • compiler/GHC/Hs/Expr.hs
    ... ... @@ -1898,7 +1898,7 @@ matchSeparator PatBindRhs = text "="
    1898 1898
     matchSeparator PatBindGuards    = text "="
    
    1899 1899
     matchSeparator StmtCtxt{}       = text "<-"
    
    1900 1900
     matchSeparator RecUpd           = text "="  -- This can be printed by the pattern
    
    1901
    -matchSeparator PatSyn           = text "<-" -- match checker trace
    
    1901
    +matchSeparator PatSynCtx        = text "<-" -- match checker trace
    
    1902 1902
     matchSeparator LazyPatCtx       = panic "unused"
    
    1903 1903
     matchSeparator ThPatSplice      = panic "unused"
    
    1904 1904
     matchSeparator ThPatQuote       = panic "unused"
    
    ... ... @@ -2494,7 +2494,7 @@ instance Outputable fn => Outputable (HsMatchContext fn) where
    2494 2494
       ppr (StmtCtxt _)            = text "StmtCtxt _"
    
    2495 2495
       ppr ThPatSplice             = text "ThPatSplice"
    
    2496 2496
       ppr ThPatQuote              = text "ThPatQuote"
    
    2497
    -  ppr PatSyn                  = text "PatSyn"
    
    2497
    +  ppr PatSynCtx               = text "PatSynCtx"
    
    2498 2498
       ppr LazyPatCtx              = text "LazyPatCtx"
    
    2499 2499
     
    
    2500 2500
     instance Outputable HsLamVariant where
    
    ... ... @@ -2538,7 +2538,7 @@ matchContextErrString RecUpd = text "record update"
    2538 2538
     matchContextErrString (ArrowMatchCtxt c)            = matchArrowContextErrString c
    
    2539 2539
     matchContextErrString ThPatSplice                   = panic "matchContextErrString"  -- Not used at runtime
    
    2540 2540
     matchContextErrString ThPatQuote                    = panic "matchContextErrString"  -- Not used at runtime
    
    2541
    -matchContextErrString PatSyn                        = text "pattern synonym"
    
    2541
    +matchContextErrString PatSynCtx                     = text "pattern synonym"
    
    2542 2542
     matchContextErrString (StmtCtxt (ParStmtCtxt c))    = matchContextErrString (StmtCtxt c)
    
    2543 2543
     matchContextErrString (StmtCtxt (TransStmtCtxt c))  = matchContextErrString (StmtCtxt c)
    
    2544 2544
     matchContextErrString (StmtCtxt (PatGuard _))       = text "pattern guard"
    
    ... ... @@ -2613,7 +2613,7 @@ pprMatchContextNoun PatBindGuards = text "pattern binding guards"
    2613 2613
     pprMatchContextNoun (ArrowMatchCtxt c)      = pprArrowMatchContextNoun c
    
    2614 2614
     pprMatchContextNoun (StmtCtxt ctxt)         = text "pattern binding in"
    
    2615 2615
                                                   $$ pprAStmtContext ctxt
    
    2616
    -pprMatchContextNoun PatSyn                  = text "pattern synonym declaration"
    
    2616
    +pprMatchContextNoun PatSynCtx               = text "pattern synonym declaration"
    
    2617 2617
     pprMatchContextNoun LazyPatCtx              = text "irrefutable pattern"
    
    2618 2618
     
    
    2619 2619
     pprMatchContextNouns :: Outputable fn => HsMatchContext fn -> SDoc
    

  • compiler/GHC/HsToCore/Pmc/Utils.hs
    ... ... @@ -93,7 +93,7 @@ exhaustiveWarningFlag (ArrowMatchCtxt c) = arrowMatchContextExhaustiveWarningFla
    93 93
     exhaustiveWarningFlag RecUpd             = Just Opt_WarnIncompletePatternsRecUpd
    
    94 94
     exhaustiveWarningFlag LazyPatCtx         = Just Opt_WarnIncompleteUniPatterns
    
    95 95
     exhaustiveWarningFlag ThPatSplice        = Nothing
    
    96
    -exhaustiveWarningFlag PatSyn             = Nothing
    
    96
    +exhaustiveWarningFlag PatSynCtx          = Nothing
    
    97 97
     exhaustiveWarningFlag ThPatQuote         = Nothing
    
    98 98
     -- Don't warn about incomplete patterns in list comprehensions, pattern guards
    
    99 99
     -- etc. They are often *supposed* to be incomplete
    

  • compiler/GHC/Rename/Bind.hs
    ... ... @@ -763,7 +763,7 @@ rnPatSynBind sig_fn bind@(PSB { psb_id = L l name
    763 763
             ; let scoped_tvs = sig_fn name
    
    764 764
     
    
    765 765
             ; ((pat', details'), fvs1) <- bindSigTyVarsFV scoped_tvs $
    
    766
    -                                      rnPat PatSyn pat $ \pat' ->
    
    766
    +                                      rnPat PatSynCtx pat $ \pat' ->
    
    767 767
              -- We check the 'RdrName's instead of the 'Name's
    
    768 768
              -- so that the binding locations are reported
    
    769 769
              -- from the left-hand side
    

  • compiler/GHC/Rename/Names.hs
    ... ... @@ -2453,8 +2453,8 @@ badImportItemErr iface decl_spec ie sub avails = do
    2453 2453
               -- Only keep imported items, and set the "HowInScope" to
    
    2454 2454
               -- "Nothing" to avoid printing "imported from..." in the suggestion
    
    2455 2455
               -- error message.
    
    2456
    -          imported_item (SimilarRdrName rdr_name (Just (ImportedBy {})))
    
    2457
    -            = Just (SimilarRdrName rdr_name Nothing)
    
    2456
    +          imported_item (SimilarRdrName rdr_name gre (Just (ImportedBy {})))
    
    2457
    +            = Just (SimilarRdrName rdr_name gre Nothing)
    
    2458 2458
               imported_item _ = Nothing
    
    2459 2459
     
    
    2460 2460
         checkIfDataCon = checkIfAvailMatches isDataConName
    

  • compiler/GHC/Rename/Unbound.hs
    ... ... @@ -18,6 +18,7 @@ module GHC.Rename.Unbound
    18 18
        , unknownNameSuggestionsMessage
    
    19 19
        , similarNameSuggestions
    
    20 20
        , fieldSelectorSuggestions
    
    21
    +   , anyQualImportSuggestions
    
    21 22
        , WhatLooking(..)
    
    22 23
        , WhereLooking(..)
    
    23 24
        , LookingFor(..)
    
    ... ... @@ -215,7 +216,7 @@ unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env
    215 216
           , map (ImportSuggestion $ rdrNameOcc tried_rdr_name) imp_suggs
    
    216 217
           , extensionSuggestions tried_rdr_name
    
    217 218
           , fieldSelectorSuggestions global_env tried_rdr_name ]
    
    218
    -    (imp_errs, imp_suggs) = importSuggestions looking_for hpt curr_mod imports tried_rdr_name
    
    219
    +    (imp_errs, imp_suggs) = sameQualImportSuggestions looking_for hpt curr_mod imports tried_rdr_name
    
    219 220
     
    
    220 221
         if_ne :: (NonEmpty a -> b) -> [a] -> [b]
    
    221 222
         if_ne _ []       = []
    
    ... ... @@ -242,7 +243,7 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env
    242 243
         all_possibilities :: [(String, SimilarName)]
    
    243 244
         all_possibilities = case what_look of
    
    244 245
           WL_None -> []
    
    245
    -      _ -> [ (showPpr dflags r, SimilarRdrName r (Just $ LocallyBoundAt loc))
    
    246
    +      _ -> [ (showPpr dflags r, SimilarRdrName r Nothing (Just $ LocallyBoundAt loc))
    
    246 247
                | (r,loc) <- local_possibilities local_env ]
    
    247 248
             ++ [ (showPpr dflags r, rp) | (r, rp) <- global_possibilities global_env ]
    
    248 249
     
    
    ... ... @@ -273,7 +274,7 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env
    273 274
     
    
    274 275
         global_possibilities :: GlobalRdrEnv -> [(RdrName, SimilarName)]
    
    275 276
         global_possibilities global_env
    
    276
    -      | tried_is_qual = [ (rdr_qual, SimilarRdrName rdr_qual (Just how))
    
    277
    +      | tried_is_qual = [ (rdr_qual, SimilarRdrName rdr_qual (Just gre) (Just how))
    
    277 278
                             | gre <- globalRdrEnvElts global_env
    
    278 279
                             , isGreOk looking_for gre
    
    279 280
                             , let occ = greOccName gre
    
    ... ... @@ -288,7 +289,7 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env
    288 289
                               rdr_unqual = mkRdrUnqual occ
    
    289 290
                         , is_relevant occ
    
    290 291
                         , sim <- case (unquals_in_scope gre, quals_only gre) of
    
    291
    -                                (how:_, _)    -> [ SimilarRdrName rdr_unqual (Just how) ]
    
    292
    +                                (how:_, _)    -> [ SimilarRdrName rdr_unqual (Just gre) (Just how) ]
    
    292 293
                                     ([],    pr:_) -> [ pr ]  -- See Note [Only-quals]
    
    293 294
                                     ([],    [])   -> [] ]
    
    294 295
     
    
    ... ... @@ -316,45 +317,74 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env
    316 317
         quals_only :: GlobalRdrElt -> [SimilarName]
    
    317 318
         -- Ones for which *only* the qualified version is in scope
    
    318 319
         quals_only (gre@GRE { gre_imp = is })
    
    319
    -      = [ (SimilarRdrName (mkRdrQual (is_as ispec) (greOccName gre)) (Just $ ImportedBy ispec))
    
    320
    +      = [ (SimilarRdrName (mkRdrQual (is_as ispec) (greOccName gre)) (Just gre) (Just $ ImportedBy ispec))
    
    320 321
             | i <- bagToList is, let ispec = is_decl i, is_qual ispec ]
    
    321 322
     
    
    323
    +-- | Provide import suggestions, without filtering by module qualification.
    
    324
    +-- Used to suggest imports for 'HasField', which doesn't care about whether a
    
    325
    +-- name is imported qualified or unqualified.
    
    326
    +--
    
    327
    +-- For example:
    
    328
    +--
    
    329
    +--  > import M1 () -- M1 exports fld1
    
    330
    +--  > import qualified M2 hiding ( fld2 )
    
    331
    +--  > x r = r.fld1              -- suggest adding 'fld1' to M1 import
    
    332
    +--  > y r = getField @"fld2" r  -- suggest unhiding 'fld' from M2 import
    
    333
    +anyQualImportSuggestions :: LookingFor -> LookupGRE GREInfo -> TcM [ImportSuggestion]
    
    334
    +anyQualImportSuggestions looking_for lookup_gre =
    
    335
    +  do { imp_info <- getImports
    
    336
    +     ; let interesting_imports = interestingImports imp_info (const True)
    
    337
    +     ; return $
    
    338
    +          importSuggestions_ looking_for interesting_imports lookup_gre
    
    339
    +     }
    
    322 340
     
    
    323
    --- | Generate errors and helpful suggestions if a qualified name Mod.foo is not in scope.
    
    324
    -importSuggestions :: LookingFor
    
    325
    -                  -> InteractiveContext -> Module
    
    326
    -                  -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion])
    
    327
    -importSuggestions looking_for ic currMod imports rdr_name
    
    328
    -  | WL_LocalOnly <- lf_where looking_for       = ([], [])
    
    329
    -  | WL_LocalTop  <- lf_where looking_for       = ([], [])
    
    341
    +-- | The given 'RdrName' is not in scope. Try to find out why that is by looking
    
    342
    +-- at the import list, to suggest e.g. changing the import list somehow.
    
    343
    +--
    
    344
    +-- For example:
    
    345
    +--
    
    346
    +-- > import qualified M1 hiding ( blah1 )
    
    347
    +-- > x = M1.blah -- suggest unhiding blah1
    
    348
    +-- > y = XX.blah1 -- import error: no imports provide the XX qualification prefix
    
    349
    +sameQualImportSuggestions
    
    350
    +  :: LookingFor
    
    351
    +  -> InteractiveContext
    
    352
    +  -> Module
    
    353
    +  -> ImportAvails
    
    354
    +  -> RdrName
    
    355
    +  -> ([ImportError], [ImportSuggestion])
    
    356
    +sameQualImportSuggestions looking_for ic currMod imports rdr_name
    
    330 357
       | not (isQual rdr_name || isUnqual rdr_name) = ([], [])
    
    331
    -  | Just name <- mod_name
    
    332
    -  , show_not_imported_line name
    
    333
    -  = ([MissingModule name], [])
    
    358
    +  | Just rdr_mod_name <- mb_rdr_mod_name
    
    359
    +  , show_not_imported_line rdr_mod_name
    
    360
    +  = ([MissingModule rdr_mod_name], [])
    
    334 361
       | is_qualified
    
    335
    -  , null helpful_imports
    
    362
    +  , null import_suggs
    
    336 363
       , (mod : mods) <- map fst interesting_imports
    
    337 364
       = ([ModulesDoNotExport (mod :| mods) (lf_which looking_for) occ_name], [])
    
    338
    -  | mod : mods <- helpful_imports_non_hiding
    
    339
    -  = ([], [CouldImportFrom (mod :| mods)])
    
    340
    -  | mod : mods <- helpful_imports_hiding
    
    341
    -  = ([], [CouldUnhideFrom (mod :| mods)])
    
    342 365
       | otherwise
    
    343
    -  = ([], [])
    
    344
    - where
    
    366
    +  = ([], import_suggs)
    
    367
    +  where
    
    368
    +
    
    369
    +  interesting_imports = interestingImports imports right_qual_import
    
    370
    +
    
    371
    +  import_suggs =
    
    372
    +    importSuggestions_ looking_for interesting_imports $
    
    373
    +      (LookupOccName (rdrNameOcc rdr_name) $ RelevantGREsFOS WantNormal)
    
    374
    +
    
    345 375
       is_qualified = isQual rdr_name
    
    346
    -  (mod_name, occ_name) = case rdr_name of
    
    376
    +  (mb_rdr_mod_name, occ_name) = case rdr_name of
    
    347 377
         Unqual occ_name        -> (Nothing, occ_name)
    
    348 378
         Qual mod_name occ_name -> (Just mod_name, occ_name)
    
    349
    -    _                      -> panic "importSuggestions: dead code"
    
    350
    -
    
    379
    +    _                      -> panic "sameQualImportSuggestions: dead code"
    
    351 380
     
    
    352
    -  -- What import statements provide "Mod" at all
    
    353
    -  -- or, if this is an unqualified name, are not qualified imports
    
    354
    -  interesting_imports = [ (mod, imp)
    
    355
    -    | (mod, mod_imports) <- M.toList (imp_mods imports)
    
    356
    -    , Just imp <- return $ pick (importedByUser mod_imports)
    
    357
    -    ]
    
    381
    +  -- See Note [When to show/hide the module-not-imported line]
    
    382
    +  show_not_imported_line :: ModuleName -> Bool                    -- #15611
    
    383
    +  show_not_imported_line modnam
    
    384
    +      | not (null interactive_imports)        = False -- 1 (interactive context)
    
    385
    +      | not (null interesting_imports)        = False -- 1 (normal module import)
    
    386
    +      | moduleName currMod == modnam          = False -- 2
    
    387
    +      | otherwise                             = True
    
    358 388
     
    
    359 389
       -- Choose the imports from the interactive context which might have provided
    
    360 390
       -- a module.
    
    ... ... @@ -362,18 +392,52 @@ importSuggestions looking_for ic currMod imports rdr_name
    362 392
         filter pick_interactive (ic_imports ic)
    
    363 393
     
    
    364 394
       pick_interactive :: InteractiveImport -> Bool
    
    365
    -  pick_interactive (IIDecl d)   | mod_name == Just (unLoc (ideclName d)) = True
    
    366
    -                                | mod_name == fmap unLoc (ideclAs d) = True
    
    367
    -  pick_interactive (IIModule m) | mod_name == Just (moduleName m) = True
    
    395
    +  pick_interactive (IIDecl d)   | mb_rdr_mod_name == Just (unLoc (ideclName d)) = True
    
    396
    +                                | mb_rdr_mod_name == fmap unLoc (ideclAs d) = True
    
    397
    +  pick_interactive (IIModule m) | mb_rdr_mod_name == Just (moduleName m) = True
    
    368 398
       pick_interactive _ = False
    
    369 399
     
    
    400
    +  right_qual_import imv =
    
    401
    +    case mb_rdr_mod_name of
    
    402
    +      -- Qual RdrName: only want qualified imports with the same module name
    
    403
    +      Just rdr_mod_name -> imv_name imv == rdr_mod_name
    
    404
    +      -- UnQual RdrName: import must be unqualified
    
    405
    +      Nothing           -> not (imv_qualified imv)
    
    406
    +
    
    407
    +-- | What import statements are relevant?
    
    408
    +--
    
    409
    +--   - If we are looking for a qualified name @Mod.blah@, which imports provide @Mod@ at all,
    
    410
    +--   - If we are looking for an unqualified name, which imports are themselves unqualified.
    
    411
    +interestingImports :: ImportAvails -> (ImportedModsVal -> Bool) -> [(Module, ImportedModsVal)]
    
    412
    +interestingImports imports ok_mod_name =
    
    413
    +  [ (mod, imp)
    
    414
    +    | (mod, mod_imports) <- M.toList (imp_mods imports)
    
    415
    +    , Just imp <- return $ pick (importedByUser mod_imports)
    
    416
    +    ]
    
    417
    +
    
    418
    +  where
    
    370 419
       -- We want to keep only one for each original module; preferably one with an
    
    371 420
       -- explicit import list (for no particularly good reason)
    
    372 421
       pick :: [ImportedModsVal] -> Maybe ImportedModsVal
    
    373
    -  pick = listToMaybe . sortBy cmp . filter select
    
    374
    -    where select imv = case mod_name of Just name -> imv_name imv == name
    
    375
    -                                        Nothing   -> not (imv_qualified imv)
    
    376
    -          cmp = on compare imv_is_hiding S.<> on SrcLoc.leftmost_smallest imv_span
    
    422
    +  pick = listToMaybe . sortBy cmp . filter ok_mod_name
    
    423
    +    where
    
    424
    +      cmp = on compare imv_is_hiding S.<> on SrcLoc.leftmost_smallest imv_span
    
    425
    +
    
    426
    +importSuggestions_
    
    427
    +  :: LookingFor
    
    428
    +  -> [(Module, ImportedModsVal)]
    
    429
    +  -> LookupGRE GREInfo
    
    430
    +  -> [ImportSuggestion]
    
    431
    +importSuggestions_ looking_for interesting_imports lookup_gre
    
    432
    +  | WL_LocalOnly <- lf_where looking_for       = []
    
    433
    +  | WL_LocalTop  <- lf_where looking_for       = []
    
    434
    +  | mod : mods <- helpful_imports_non_hiding
    
    435
    +  = [CouldImportFrom (mod :| mods)]
    
    436
    +  | mod : mods <- helpful_imports_hiding
    
    437
    +  = [CouldUnhideFrom (mod :| mods)]
    
    438
    +  | otherwise
    
    439
    +  = []
    
    440
    + where
    
    377 441
     
    
    378 442
       -- Which of these would export a 'foo'
    
    379 443
       -- (all of these are restricted imports, because if they were not, we
    
    ... ... @@ -382,21 +446,13 @@ importSuggestions looking_for ic currMod imports rdr_name
    382 446
         where helpful (_,imv)
    
    383 447
                 = any (isGreOk looking_for) $
    
    384 448
                   lookupGRE (imv_all_exports imv)
    
    385
    -                (LookupOccName occ_name $ RelevantGREsFOS WantNormal)
    
    449
    +                lookup_gre
    
    386 450
     
    
    387 451
       -- Which of these do that because of an explicit hiding list resp. an
    
    388 452
       -- explicit import list
    
    389 453
       (helpful_imports_hiding, helpful_imports_non_hiding)
    
    390 454
         = partition (imv_is_hiding . snd) helpful_imports
    
    391 455
     
    
    392
    -  -- See Note [When to show/hide the module-not-imported line]
    
    393
    -  show_not_imported_line :: ModuleName -> Bool                    -- #15611
    
    394
    -  show_not_imported_line modnam
    
    395
    -      | not (null interactive_imports)        = False -- 1 (interactive context)
    
    396
    -      | not (null interesting_imports)        = False -- 1 (normal module import)
    
    397
    -      | moduleName currMod == modnam          = False -- 2
    
    398
    -      | otherwise                             = True
    
    399
    -
    
    400 456
     extensionSuggestions :: RdrName -> [GhcHint]
    
    401 457
     extensionSuggestions rdrName
    
    402 458
       | rdrName == mkUnqual varName (fsLit "mdo") ||
    

  • compiler/GHC/Tc/Errors.hs
    ... ... @@ -17,6 +17,8 @@ module GHC.Tc.Errors(
    17 17
     
    
    18 18
     import GHC.Prelude
    
    19 19
     
    
    20
    +import GHC.Builtin.Names (hasFieldClassName)
    
    21
    +
    
    20 22
     import GHC.Driver.Env (hsc_units)
    
    21 23
     import GHC.Driver.DynFlags
    
    22 24
     import GHC.Driver.Ppr
    
    ... ... @@ -31,6 +33,7 @@ import GHC.Tc.Errors.Ppr
    31 33
     import GHC.Tc.Types.Constraint
    
    32 34
     import GHC.Tc.Types.CtLoc
    
    33 35
     import GHC.Tc.Utils.TcMType
    
    36
    +import GHC.Tc.Utils.Env (tcLookupId, tcLookupDataCon)
    
    34 37
     import GHC.Tc.Zonk.Type
    
    35 38
     import GHC.Tc.Utils.TcType
    
    36 39
     import GHC.Tc.Zonk.TcType
    
    ... ... @@ -43,6 +46,7 @@ import {-# SOURCE #-} GHC.Tc.Errors.Hole ( findValidHoleFits, getHoleFitDispConf
    43 46
     import GHC.Types.Name
    
    44 47
     import GHC.Types.Name.Reader
    
    45 48
     import GHC.Types.Id
    
    49
    +import GHC.Types.Id.Info (IdDetails(..), RecSelParent (..))
    
    46 50
     import GHC.Types.Var
    
    47 51
     import GHC.Types.Var.Set
    
    48 52
     import GHC.Types.Var.Env
    
    ... ... @@ -50,13 +54,18 @@ import GHC.Types.Name.Env
    50 54
     import GHC.Types.SrcLoc
    
    51 55
     import GHC.Types.Basic
    
    52 56
     import GHC.Types.Error
    
    57
    +import GHC.Types.Hint (SimilarName (..))
    
    53 58
     import qualified GHC.Types.Unique.Map as UM
    
    59
    +import GHC.Types.Unique.Set (nonDetEltsUniqSet)
    
    54 60
     
    
    55 61
     import GHC.Unit.Module
    
    56 62
     import qualified GHC.LanguageExtensions as LangExt
    
    57 63
     
    
    64
    +import GHC.Core.PatSyn (PatSyn)
    
    58 65
     import GHC.Core.Predicate
    
    59 66
     import GHC.Core.Type
    
    67
    +import GHC.Core.Class (className)
    
    68
    +import GHC.Core.ConLike (isExistentialRecordField, ConLike (..))
    
    60 69
     import GHC.Core.Coercion
    
    61 70
     import GHC.Core.TyCo.Ppr     ( pprTyVars )
    
    62 71
     import GHC.Core.TyCo.Tidy
    
    ... ... @@ -75,13 +84,18 @@ import GHC.Data.List.SetOps ( equivClasses, nubOrdBy )
    75 84
     import GHC.Data.Maybe
    
    76 85
     import qualified GHC.Data.Strict as Strict
    
    77 86
     
    
    87
    +
    
    88
    +import Language.Haskell.Syntax.Basic (FieldLabelString(..))
    
    89
    +
    
    78 90
     import Control.Monad      ( unless, when, foldM, forM_ )
    
    91
    +import Data.Bifunctor     ( bimap )
    
    79 92
     import Data.Foldable      ( toList )
    
    80 93
     import Data.Function      ( on )
    
    81 94
     import Data.List          ( partition, union, sort, sortBy )
    
    82 95
     import Data.List.NonEmpty ( NonEmpty(..), nonEmpty )
    
    83 96
     import qualified Data.List.NonEmpty as NE
    
    84 97
     import Data.Ord         ( comparing )
    
    98
    +import Data.Either (partitionEithers)
    
    85 99
     
    
    86 100
     {-
    
    87 101
     ************************************************************************
    
    ... ... @@ -1470,8 +1484,8 @@ coercion.
    1470 1484
     mkIrredErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    
    1471 1485
     mkIrredErr ctxt items
    
    1472 1486
       = do { (ctxt, binds, item1) <- relevantBindings True ctxt item1
    
    1473
    -       ; let msg = important ctxt $ mkPlainMismatchMsg $
    
    1474
    -                   CouldNotDeduce (getUserGivens ctxt) (item1 :| others) Nothing
    
    1487
    +       ; couldNotDeduceErr <- mkCouldNotDeduceErr (getUserGivens ctxt) (item1 :| others) Nothing
    
    1488
    +       ; let msg = important ctxt $ mkPlainMismatchMsg couldNotDeduceErr
    
    1475 1489
            ; return $ add_relevant_bindings binds msg  }
    
    1476 1490
       where
    
    1477 1491
         item1:|others = tryFilter (not . ei_suppress) items
    
    ... ... @@ -1851,6 +1865,7 @@ reportEqErr :: SolverReportErrCtxt
    1851 1865
                 -> TcM TcSolverReportMsg
    
    1852 1866
     reportEqErr ctxt item ty1 ty2
    
    1853 1867
       = do
    
    1868
    +    mismatch <- misMatchOrCND ctxt item ty1 ty2
    
    1854 1869
         mb_coercible_info <- if errorItemEqRel item == ReprEq
    
    1855 1870
                              then coercible_msg ty1 ty2
    
    1856 1871
                              else return Nothing
    
    ... ... @@ -1862,7 +1877,6 @@ reportEqErr ctxt item ty1 ty2
    1862 1877
                           , mismatchAmbiguityInfo = eqInfos
    
    1863 1878
                           , mismatchCoercibleInfo = mb_coercible_info }
    
    1864 1879
       where
    
    1865
    -    mismatch = misMatchOrCND ctxt item ty1 ty2
    
    1866 1880
         eqInfos  = eqInfoMsgs ty1 ty2
    
    1867 1881
     
    
    1868 1882
     coercible_msg :: TcType -> TcType -> TcM (Maybe CoercibleMsg)
    
    ... ... @@ -1894,6 +1908,7 @@ mkTyVarEqErr' ctxt item tv1 ty2
    1894 1908
       -- try it before anything more complicated.
    
    1895 1909
       | check_eq_result `cterHasProblem` cteImpredicative
    
    1896 1910
       = do
    
    1911
    +    headline_msg <- misMatchOrCND ctxt item ty1 ty2
    
    1897 1912
         tyvar_eq_info <- extraTyVarEqInfo (tv1, Nothing) ty2
    
    1898 1913
         let
    
    1899 1914
             poly_msg = CannotUnifyWithPolytype item tv1 ty2 mb_tv_info
    
    ... ... @@ -1917,6 +1932,7 @@ mkTyVarEqErr' ctxt item tv1 ty2
    1917 1932
         || errorItemEqRel item == ReprEq
    
    1918 1933
          -- The cases below don't really apply to ReprEq (except occurs check)
    
    1919 1934
       = do
    
    1935
    +    headline_msg <- misMatchOrCND ctxt item ty1 ty2
    
    1920 1936
         tv_extra <- extraTyVarEqInfo (tv1, Nothing) ty2
    
    1921 1937
         reason <- if errorItemEqRel item == ReprEq
    
    1922 1938
                   then RepresentationalEq tv_extra <$> coercible_msg ty1 ty2
    
    ... ... @@ -1933,23 +1949,24 @@ mkTyVarEqErr' ctxt item tv1 ty2
    1933 1949
         --
    
    1934 1950
         -- Use tyCoVarsOfType because it might have begun as the canonical
    
    1935 1951
         -- constraint (Dual (Dual a)) ~ a, and been swizzled by mkEqnErr_help
    
    1936
    -  = let ambiguity_infos = eqInfoMsgs ty1 ty2
    
    1952
    +  = do headline_msg <- misMatchOrCND ctxt item ty1 ty2
    
    1953
    +       let ambiguity_infos = eqInfoMsgs ty1 ty2
    
    1937 1954
     
    
    1938
    -        interesting_tyvars = filter (not . noFreeVarsOfType . tyVarKind) $
    
    1939
    -                             filter isTyVar $
    
    1940
    -                             fvVarList $
    
    1941
    -                             tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2
    
    1955
    +           interesting_tyvars = filter (not . noFreeVarsOfType . tyVarKind) $
    
    1956
    +                                filter isTyVar $
    
    1957
    +                                fvVarList $
    
    1958
    +                                tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2
    
    1942 1959
     
    
    1943
    -        occurs_err =
    
    1944
    -          OccursCheck
    
    1945
    -            { occursCheckInterestingTyVars = interesting_tyvars
    
    1946
    -            , occursCheckAmbiguityInfos    = ambiguity_infos }
    
    1947
    -        main_msg =
    
    1948
    -          CannotUnifyVariable
    
    1949
    -            { mismatchMsg       = headline_msg
    
    1950
    -            , cannotUnifyReason = occurs_err }
    
    1960
    +           occurs_err =
    
    1961
    +             OccursCheck
    
    1962
    +               { occursCheckInterestingTyVars = interesting_tyvars
    
    1963
    +               , occursCheckAmbiguityInfos    = ambiguity_infos }
    
    1964
    +           main_msg =
    
    1965
    +             CannotUnifyVariable
    
    1966
    +               { mismatchMsg       = headline_msg
    
    1967
    +               , cannotUnifyReason = occurs_err }
    
    1951 1968
     
    
    1952
    -    in return main_msg
    
    1969
    +       return main_msg
    
    1953 1970
     
    
    1954 1971
       -- If the immediately-enclosing implication has 'tv' a skolem, and
    
    1955 1972
       -- we know by now its an InferSkol kind of skolem, then presumably
    
    ... ... @@ -2005,7 +2022,6 @@ mkTyVarEqErr' ctxt item tv1 ty2
    2005 2022
             -- Consider an ambiguous top-level constraint (a ~ F a)
    
    2006 2023
             -- Not an occurs check, because F is a type function.
    
    2007 2024
       where
    
    2008
    -    headline_msg = misMatchOrCND ctxt item ty1 ty2
    
    2009 2025
         mismatch_msg = mkMismatchMsg item ty1 ty2
    
    2010 2026
     
    
    2011 2027
         -- The following doesn't use the cterHasProblem mechanism because
    
    ... ... @@ -2073,7 +2089,7 @@ eqInfoMsgs ty1 ty2
    2073 2089
                   = Nothing
    
    2074 2090
     
    
    2075 2091
     misMatchOrCND :: SolverReportErrCtxt -> ErrorItem
    
    2076
    -              -> TcType -> TcType -> MismatchMsg
    
    2092
    +              -> TcType -> TcType -> TcM MismatchMsg
    
    2077 2093
     -- If oriented then ty1 is actual, ty2 is expected
    
    2078 2094
     misMatchOrCND ctxt item ty1 ty2
    
    2079 2095
       | insoluble_item   -- See Note [Insoluble mis-match]
    
    ... ... @@ -2082,10 +2098,10 @@ misMatchOrCND ctxt item ty1 ty2
    2082 2098
         || null givens
    
    2083 2099
       = -- If the equality is unconditionally insoluble
    
    2084 2100
         -- or there is no context, don't report the context
    
    2085
    -    mkMismatchMsg item ty1 ty2
    
    2101
    +    return $ mkMismatchMsg item ty1 ty2
    
    2086 2102
     
    
    2087 2103
       | otherwise
    
    2088
    -  = CouldNotDeduce givens (item :| []) (Just $ CND_Extra level ty1 ty2)
    
    2104
    +  = mkCouldNotDeduceErr givens (item :| []) (Just $ CND_ExpectedActual level ty1 ty2)
    
    2089 2105
     
    
    2090 2106
       where
    
    2091 2107
         insoluble_item = case ei_m_reason item of
    
    ... ... @@ -2275,9 +2291,8 @@ mkQCErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM
    2275 2291
     mkQCErr ctxt items
    
    2276 2292
       | item1 :| _ <- tryFilter (not . ei_suppress) items
    
    2277 2293
         -- Ignore multiple qc-errors on the same line
    
    2278
    -  = do { let msg = mkPlainMismatchMsg $
    
    2279
    -                   CouldNotDeduce (getUserGivens ctxt) (item1 :| []) Nothing
    
    2280
    -       ; return $ important ctxt msg }
    
    2294
    +  = do { couldNotDeduceErr <- mkCouldNotDeduceErr (getUserGivens ctxt) (item1 :| []) Nothing
    
    2295
    +       ; return $ important ctxt $ mkPlainMismatchMsg couldNotDeduceErr }
    
    2281 2296
     
    
    2282 2297
     
    
    2283 2298
     mkDictErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
    
    ... ... @@ -2292,16 +2307,9 @@ mkDictErr ctxt orig_items
    2292 2307
            -- But we report only one of them (hence 'head') because they all
    
    2293 2308
            -- have the same source-location origin, to try avoid a cascade
    
    2294 2309
            -- of error from one location
    
    2295
    -       ; ( err, (imp_errs, hints) ) <-
    
    2296
    -           mk_dict_err ctxt (head (no_inst_items ++ overlap_items))
    
    2297
    -       ; return $
    
    2298
    -           SolverReport
    
    2299
    -             { sr_important_msg = SolverReportWithCtxt ctxt err
    
    2300
    -             , sr_supplementary = [ SupplementaryImportErrors imps
    
    2301
    -                                  | imps <- maybeToList (NE.nonEmpty imp_errs) ]
    
    2302
    -             , sr_hints = hints
    
    2303
    -             }
    
    2304
    -        }
    
    2310
    +       ; err <- mk_dict_err ctxt (head (no_inst_items ++ overlap_items))
    
    2311
    +       ; return $ important ctxt err
    
    2312
    +       }
    
    2305 2313
       where
    
    2306 2314
         items = tryFilter (not . ei_suppress) orig_items
    
    2307 2315
     
    
    ... ... @@ -2335,28 +2343,29 @@ mkDictErr ctxt orig_items
    2335 2343
     --     matching and unifying instances, and say "The choice depends on the instantion of ...,
    
    2336 2344
     --     and the result of evaluating ...".
    
    2337 2345
     mk_dict_err :: HasCallStack => SolverReportErrCtxt -> (ErrorItem, ClsInstLookupResult)
    
    2338
    -            -> TcM ( TcSolverReportMsg, ([ImportError], [GhcHint]) )
    
    2346
    +            -> TcM TcSolverReportMsg
    
    2339 2347
     mk_dict_err ctxt (item, (matches, pot_unifiers, unsafe_overlapped))
    
    2340 2348
       = case (NE.nonEmpty matches, NE.nonEmpty unsafe_overlapped) of
    
    2341 2349
       (Nothing, _)  -> do -- No matches but perhaps several unifiers
    
    2342 2350
         { (_, rel_binds, item) <- relevantBindings True ctxt item
    
    2343 2351
         ; candidate_insts <- get_candidate_instances
    
    2344
    -    ; (imp_errs, field_suggestions) <- record_field_suggestions item
    
    2345
    -    ; return (CannotResolveInstance item unifiers candidate_insts rel_binds, (imp_errs, field_suggestions)) }
    
    2352
    +    ; mb_noBuiltinInst_msg <- getNoBuiltinInstMsg item
    
    2353
    +    ; return $
    
    2354
    +        CannotResolveInstance item unifiers candidate_insts rel_binds mb_noBuiltinInst_msg
    
    2355
    +    }
    
    2346 2356
     
    
    2347 2357
       -- Some matches => overlap errors
    
    2348 2358
       (Just matchesNE, Nothing) -> return $
    
    2349
    -    ( OverlappingInstances item (NE.map fst matchesNE) unifiers, ([], []))
    
    2359
    +    OverlappingInstances item (NE.map fst matchesNE) unifiers
    
    2350 2360
     
    
    2351 2361
       (Just (match :| []), Just unsafe_overlappedNE) -> return $
    
    2352
    -    ( UnsafeOverlap item (fst match) (NE.map fst unsafe_overlappedNE), ([], []))
    
    2362
    +    UnsafeOverlap item (fst match) (NE.map fst unsafe_overlappedNE)
    
    2353 2363
       (Just matches@(_ :| _), Just overlaps) ->
    
    2354 2364
         pprPanic "mk_dict_err: multiple matches with overlap" $
    
    2355 2365
           vcat [ text "matches:" <+> ppr matches
    
    2356 2366
                , text "overlaps:" <+> ppr overlaps
    
    2357 2367
                ]
    
    2358 2368
       where
    
    2359
    -    orig        = errorItemOrigin item
    
    2360 2369
         pred        = errorItemPred item
    
    2361 2370
         (clas, tys) = getClassPredTys pred
    
    2362 2371
         unifiers    = getCoherentUnifiers pot_unifiers
    
    ... ... @@ -2381,43 +2390,6 @@ mk_dict_err ctxt (item, (matches, pot_unifiers, unsafe_overlapped))
    2381 2390
             in different_names && same_occ_names
    
    2382 2391
           | otherwise = False
    
    2383 2392
     
    
    2384
    -    -- See Note [Out-of-scope fields with -XOverloadedRecordDot]
    
    2385
    -    record_field_suggestions :: ErrorItem -> TcM ([ImportError], [GhcHint])
    
    2386
    -    record_field_suggestions item = flip (maybe $ return ([], noHints)) record_field $ \name ->
    
    2387
    -       do { glb_env <- getGlobalRdrEnv
    
    2388
    -          ; lcl_env <- getLocalRdrEnv
    
    2389
    -          ; let field_name_hints = report_no_fieldnames item
    
    2390
    -          ; (errs, hints) <- if occ_name_in_scope glb_env lcl_env name
    
    2391
    -              then return ([], noHints)
    
    2392
    -              else unknownNameSuggestions emptyLocalRdrEnv WL_RecField (mkRdrUnqual name)
    
    2393
    -          ; pure (errs, hints ++ field_name_hints)
    
    2394
    -          }
    
    2395
    -
    
    2396
    -    -- get type names from instance
    
    2397
    -    -- resolve the type - if it's in scope is it a record?
    
    2398
    -    -- if it's a record, report an error - the record name + the field that could not be found
    
    2399
    -    report_no_fieldnames :: ErrorItem -> [GhcHint]
    
    2400
    -    report_no_fieldnames item
    
    2401
    -       | Just (EvVarDest evvar) <- ei_evdest item
    
    2402
    -       -- we can assume that here we have a `HasField @Symbol x r a` instance
    
    2403
    -       -- because of GetFieldOrigin in record_field
    
    2404
    -       , Just (_, [_symbol, x, r, a]) <- tcSplitTyConApp_maybe (varType evvar)
    
    2405
    -       , Just (r_tycon, _) <- tcSplitTyConApp_maybe r
    
    2406
    -       , Just x_name <- isStrLitTy x
    
    2407
    -       -- we check that this is a record type by checking whether it has any
    
    2408
    -       -- fields (in scope)
    
    2409
    -       , not . null $ tyConFieldLabels r_tycon
    
    2410
    -       = [RemindRecordMissingField x_name r a]
    
    2411
    -       | otherwise = []
    
    2412
    -
    
    2413
    -    occ_name_in_scope glb_env lcl_env occ_name = not $
    
    2414
    -      null (lookupGRE glb_env (LookupOccName occ_name (RelevantGREsFOS WantNormal))) &&
    
    2415
    -      isNothing (lookupLocalRdrOcc lcl_env occ_name)
    
    2416
    -
    
    2417
    -    record_field = case orig of
    
    2418
    -      GetFieldOrigin name -> Just (mkVarOccFS name)
    
    2419
    -      _                   -> Nothing
    
    2420
    -
    
    2421 2393
     {- Note [Report candidate instances]
    
    2422 2394
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2423 2395
     If we have an unsolved (Num Int), where `Int` is not the Prelude Int,
    
    ... ... @@ -2475,6 +2447,245 @@ results in
    2475 2447
           in the import of ‘Data.Monoid’
    
    2476 2448
     -}
    
    2477 2449
     
    
    2450
    +mkCouldNotDeduceErr
    
    2451
    +  :: [UserGiven]
    
    2452
    +  -> NonEmpty ErrorItem
    
    2453
    +  -> Maybe CND_ExpectedActual
    
    2454
    +  -> TcM MismatchMsg
    
    2455
    +mkCouldNotDeduceErr user_givens items@(item :| _) mb_ea
    
    2456
    +  = do { mb_noBuiltinInst_info <- getNoBuiltinInstMsg item
    
    2457
    +       ; return $ CouldNotDeduce user_givens items mb_ea mb_noBuiltinInst_info }
    
    2458
    +
    
    2459
    +getNoBuiltinInstMsg :: ErrorItem -> TcM (Maybe NoBuiltinInstanceMsg)
    
    2460
    +getNoBuiltinInstMsg item =
    
    2461
    +  do { rdr_env <- getGlobalRdrEnv
    
    2462
    +     ; fam_envs <- tcGetFamInstEnvs
    
    2463
    +     ; mbNoHasFieldMsg <- hasFieldInfo_maybe rdr_env fam_envs item
    
    2464
    +     ; return $ fmap NoBuiltinHasFieldMsg mbNoHasFieldMsg
    
    2465
    +     }
    
    2466
    +
    
    2467
    +{- Note [Error messages for unsolved HasField constraints]
    
    2468
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2469
    +The HasField type-class has special instance solving logic, implemented in
    
    2470
    +'GHC.Tc.Instance.Class.{matchHasField,lookupHasFieldLabel}'. This logic is a
    
    2471
    +bit complex, so it's useful to explain to the user why GHC might have failed to
    
    2472
    +solve a 'HasField' constraint. GHC will emit the following error messages for
    
    2473
    +an unsolved constraint of the form 'HasField fld_name rec_ty fld_ty'.
    
    2474
    +These come in two flavours
    
    2475
    +
    
    2476
    +  HF1.
    
    2477
    +    Actionable hints: suggest similarly named fields (in case of mis-spelling)
    
    2478
    +    or provide import suggestions (e.g. out of scope field).
    
    2479
    +    See 'GHC.Tc.Errors.Ppr.hasFieldMsgHints' which takes the returned
    
    2480
    +    'HasFieldMsg' and produces the hints we display to the user.
    
    2481
    +
    
    2482
    +    This depends on whether 'rec_ty' is a known fixed TyCon or not.
    
    2483
    +
    
    2484
    +    HF1a. If 'rec_ty' is a known record TyCon:
    
    2485
    +          - If 'fld_name' is a record field of that TyCon, but it's not in scope,
    
    2486
    +            then suggest importing it.
    
    2487
    +          - Otherwise, we suggest similarly named fields, prioritising similar
    
    2488
    +            name suggestions for record fields from that same TyCon.
    
    2489
    +
    
    2490
    +    HF1b. If 'rec_ty' is not a fixed TyCon (e.g. it's a metavariable):
    
    2491
    +          - If 'fld_name' is an in-scope record field, don't suggest anything.
    
    2492
    +          - Otherwise, suggest similar names.
    
    2493
    +
    
    2494
    +  HF2. Observations. GHC points out a fact to the user which might help them
    
    2495
    +       understand the problem:
    
    2496
    +
    
    2497
    +    HF2a. 'fld_name' is not a string literal.
    
    2498
    +          This is useful when the user has forgotten the quotes, e.g. they
    
    2499
    +          have written 'getField @myFieldName' instead of 'getField @"myFieldName"'.
    
    2500
    +
    
    2501
    +    HF2b. 'rec_ty' is a TyCon without any fields, e.g. 'Int' or 'Bool'.
    
    2502
    +
    
    2503
    +    HF2c. The record field type 'fld_ty' contains existentials variables
    
    2504
    +          or foralls. In the former case GHC doesn't generate a field selector
    
    2505
    +          at all (it's a naughty record selector), while in the latter GHC
    
    2506
    +          doesn't solve the constraint, because class instance arguments
    
    2507
    +          can't contain foralls.
    
    2508
    +
    
    2509
    +    HF2d. The record field is a pattern synonym record field.
    
    2510
    +          GHC does not generate 'HasField' instances for pattern synonym fields.
    
    2511
    +
    
    2512
    +    HF2e. The user is using -XRebindableSyntax, and this is not actually the
    
    2513
    +          built-in HasField which GHC has special solving logic for.
    
    2514
    +
    
    2515
    +          This can happen rather easily, because the current usage of
    
    2516
    +          -XOverloadedRecordUpdate requires enabling -XRebindableSyntax and
    
    2517
    +          defining a custom 'setField' function.
    
    2518
    +-}
    
    2519
    +
    
    2520
    +-- | Try to produce an explanatory message for why GHC was not able to use
    
    2521
    +-- a built-in instance to solve a 'HasField' constraint.
    
    2522
    +--
    
    2523
    +-- See Note [Error messages for unsolved HasField constraints]
    
    2524
    +hasFieldInfo_maybe :: GlobalRdrEnv -> FamInstEnvs -> ErrorItem -> TcM (Maybe HasFieldMsg)
    
    2525
    +hasFieldInfo_maybe rdr_env fam_inst_envs item
    
    2526
    +  | Just (x_ty, rec_ty, _wanted_field_ty) <- hasField_maybe (errorItemPred item)
    
    2527
    +
    
    2528
    +  -- This function largely replicates the logic
    
    2529
    +  -- of 'GHC.Tc.Instance.Class.{matchHasField,lookupHasFieldLabel}'.
    
    2530
    +  --
    
    2531
    +  -- When that function fails to return a built-in HasField instance,
    
    2532
    +  -- this function should generate an appropriate message which can be
    
    2533
    +  -- displayed to the user as a hint.
    
    2534
    +
    
    2535
    +  = case isStrLitTy x_ty of
    
    2536
    +    { Nothing ->
    
    2537
    +        -- (HF2a) Field label is not a literal string.
    
    2538
    +        return $ Just $ NotALiteralFieldName x_ty
    
    2539
    +    ; Just x ->
    
    2540
    + do { dflags <- getDynFlags
    
    2541
    +    ; let x_fl = FieldLabelString x
    
    2542
    +          looking_for_field = LF WL_RecField WL_Global
    
    2543
    +          fld_var_occ = mkVarOccFS x
    
    2544
    +          lkup_fld_occ = LookupOccName fld_var_occ (RelevantGREsFOS WantField)
    
    2545
    +          similar_names =
    
    2546
    +            similarNameSuggestions looking_for_field
    
    2547
    +              dflags rdr_env emptyLocalRdrEnv (mkRdrUnqual fld_var_occ)
    
    2548
    +    ; (patsyns, suggs) <- partitionEithers <$> mapMaybeM with_parent similar_names
    
    2549
    +    ; imp_suggs <- anyQualImportSuggestions looking_for_field lkup_fld_occ
    
    2550
    +    ; case splitTyConApp_maybe rec_ty of
    
    2551
    +    { Nothing -> do
    
    2552
    +        -- (HF1b) Similar name and import suggestions with unknown TyCon.
    
    2553
    +        --
    
    2554
    +        -- Don't say 'rec is not a record type' if 'rec' is e.g. a type variable.
    
    2555
    +        -- That's not really helpful, especially if 'rec' is a metavariable,
    
    2556
    +        -- in which case this is most likely an ambiguity issue.
    
    2557
    +        let gres = lookupGRE rdr_env lkup_fld_occ
    
    2558
    +        case gres of
    
    2559
    +          _:_ ->
    
    2560
    +            -- If the name was in scope, don't give "similar name" suggestions.
    
    2561
    +            return Nothing
    
    2562
    +          [] -> do
    
    2563
    +            return $ Just $
    
    2564
    +              SuggestSimilarFields Nothing x_fl suggs patsyns imp_suggs
    
    2565
    +    ; Just (rec_tc, rec_args)
    
    2566
    +        | let rec_rep_tc = fstOf3 (tcLookupDataFamInst fam_inst_envs rec_tc rec_args)
    
    2567
    +        ->
    
    2568
    +      if null $ tyConFieldLabels rec_rep_tc
    
    2569
    +      then
    
    2570
    +        -- (HF2b) Not a record TyCon
    
    2571
    +        return $ Just $ NotARecordType rec_ty
    
    2572
    +      else
    
    2573
    +      case lookupTyConFieldLabel x_fl rec_rep_tc of
    
    2574
    +    { Nothing -> do
    
    2575
    +        -- (HF1a) Similar name and import suggestions with known TyCon.
    
    2576
    +        return $ Just $
    
    2577
    +          SuggestSimilarFields (Just (rec_tc, rec_rep_tc)) x_fl suggs patsyns imp_suggs
    
    2578
    +    ; Just fl ->
    
    2579
    +        -- The TyCon does have the field, so the issue might be that
    
    2580
    +        -- it's not in scope or that the field is existential or higher-rank.
    
    2581
    +      case lookupGRE_FieldLabel rdr_env fl of
    
    2582
    +    { Nothing -> do
    
    2583
    +        -- (HF1a) Not in scope. Try to suggest importing the field.
    
    2584
    +        let lookup_gre =
    
    2585
    +              LookupExactName
    
    2586
    +                { lookupExactName = flSelector fl
    
    2587
    +                , lookInAllNameSpaces = False }
    
    2588
    +        imp_suggs <- anyQualImportSuggestions looking_for_field lookup_gre
    
    2589
    +        return $ Just $ OutOfScopeField rec_tc fl imp_suggs
    
    2590
    +    ; Just gre ->
    
    2591
    +      let con1_nm =
    
    2592
    +            case nonDetEltsUniqSet $ recFieldCons $ fieldGREInfo gre of
    
    2593
    +                   n : _ -> n
    
    2594
    +                   [] -> pprPanic "record field with no constructors" (ppr fl)
    
    2595
    +      in case con1_nm of
    
    2596
    +    { PatSynName {} ->
    
    2597
    +      -- 'lookupTyConFieldLabel' always returns a DataCon field
    
    2598
    +      pprPanic "hasFieldInfo_maybe: PatSyn" $
    
    2599
    +        vcat [ text "tc:" <+> ppr rec_tc
    
    2600
    +             , text "rep_tc:" <+> ppr rec_rep_tc
    
    2601
    +             , text "con1_nm:" <+> ppr con1_nm
    
    2602
    +             ]
    
    2603
    +    ; DataConName dc1_nm -> do
    
    2604
    +      dc1 <- tcLookupDataCon dc1_nm
    
    2605
    +      let orig_field_ty = dataConFieldType dc1 (flLabel fl)
    
    2606
    +      return $
    
    2607
    +        -- (HF2c) Existential or higher-rank field.
    
    2608
    +        -- See 'GHC.Tc.Instance.Class.matchHasField', which
    
    2609
    +        -- has these same two conditions.
    
    2610
    +        if |  isExistentialRecordField orig_field_ty (RealDataCon dc1)
    
    2611
    +              -- NB: use 'orig_field_ty' and not 'idType sel_id',
    
    2612
    +              -- because the latter is 'unitTy' when there are existentials.
    
    2613
    +           -> Just $ FieldTooFancy rec_tc x_fl FieldHasExistential
    
    2614
    +           | not $ isTauTy orig_field_ty
    
    2615
    +           -> Just $ FieldTooFancy rec_tc x_fl FieldHasForAlls
    
    2616
    +           | otherwise
    
    2617
    +           -> Nothing
    
    2618
    +             -- Not sure what went wrong. Usually not a type error
    
    2619
    +             -- in the field type, because the functional dependency
    
    2620
    +             -- would cause a genuine equality error.
    
    2621
    +  }}}}}}
    
    2622
    +
    
    2623
    +  -- (HF2e) It's a custom HasField constraint, not the one from GHC.Records.
    
    2624
    +  | Just (tc, _) <- splitTyConApp_maybe (errorItemPred item)
    
    2625
    +  , getOccString tc == "HasField"
    
    2626
    +  , isHasFieldOrigin (errorItemOrigin item)
    
    2627
    +  = return $ Just $ CustomHasField tc
    
    2628
    +
    
    2629
    +  | otherwise
    
    2630
    +  = return Nothing
    
    2631
    +
    
    2632
    +  where
    
    2633
    +
    
    2634
    +    get_parent_nm :: Name -> TcM (Maybe (Either PatSyn TyCon))
    
    2635
    +    get_parent_nm nm =
    
    2636
    +      do { fld_id <- tcLookupId nm
    
    2637
    +         ; return $
    
    2638
    +             case idDetails fld_id of
    
    2639
    +               RecSelId { sel_tycon = parent } ->
    
    2640
    +                 case parent of
    
    2641
    +                  RecSelData tc ->
    
    2642
    +                     Just $ Right tc
    
    2643
    +                  RecSelPatSyn ps ->
    
    2644
    +                    -- (HF2d) PatSyn record fields don't contribute 'HasField'
    
    2645
    +                    --        instances, so tell the user about that.
    
    2646
    +                    Just $ Left ps
    
    2647
    +               _ -> Nothing
    
    2648
    +         }
    
    2649
    +
    
    2650
    +    get_parent :: SimilarName -> TcM (Maybe (Either PatSyn TyCon))
    
    2651
    +    get_parent (SimilarName nm) = get_parent_nm nm
    
    2652
    +    get_parent (SimilarRdrName _ mb_gre _) =
    
    2653
    +      case mb_gre of
    
    2654
    +        Nothing -> return Nothing
    
    2655
    +        Just gre -> get_parent_nm $ greName gre
    
    2656
    +
    
    2657
    +    with_parent :: SimilarName
    
    2658
    +                -> TcM (Maybe (Either (PatSyn, SimilarName) (TyCon, SimilarName)))
    
    2659
    +    with_parent n = fmap (bimap (,n) (,n)) <$> get_parent n
    
    2660
    +
    
    2661
    +-- | Is this constraint definitely 'HasField'?
    
    2662
    +hasField_maybe :: PredType -> Maybe (Type, Type, Type)
    
    2663
    +hasField_maybe pred =
    
    2664
    +  case classifyPredType pred of
    
    2665
    +    ClassPred cls tys
    
    2666
    +      | className cls == hasFieldClassName
    
    2667
    +      , [ _k, _rec_rep, _fld_rep, x_ty, rec_ty, fld_ty ] <- tys
    
    2668
    +      -> Just (x_ty, rec_ty, fld_ty)
    
    2669
    +    _ -> Nothing
    
    2670
    +  -- NB: we deliberately don't handle rebound 'HasField' (with -XRebindableSyntax),
    
    2671
    +  -- as GHC only has built-in instances for the built-in 'HasField' class.
    
    2672
    +
    
    2673
    +-- | Does this constraint arise from GHC internal mechanisms that desugar to
    
    2674
    +-- usage of the 'HasField' typeclass (e.g. OverloadedRecordDot, etc)?
    
    2675
    +--
    
    2676
    +-- Just used heuristically to decide whether to print an informative message to
    
    2677
    +-- the user (see (H2e) in Note [Error messages for unsolved HasField constraints]).
    
    2678
    +isHasFieldOrigin :: CtOrigin -> Bool
    
    2679
    +isHasFieldOrigin = \case
    
    2680
    +  OccurrenceOf n ->
    
    2681
    +    -- A heuristic...
    
    2682
    +    getOccString n `elem` ["getField", "setField"]
    
    2683
    +  OccurrenceOfRecSel {} -> True
    
    2684
    +  RecordUpdOrigin {} -> True
    
    2685
    +  RecordFieldProjectionOrigin {} -> True
    
    2686
    +  GetFieldOrigin {} -> True
    
    2687
    +  _ -> False
    
    2688
    +
    
    2478 2689
     -----------------------
    
    2479 2690
     -- relevantBindings looks at the value environment and finds values whose
    
    2480 2691
     -- types mention any of the offending type variables.  It has to be
    

  • compiler/GHC/Tc/Errors/Ppr.hs
    ... ... @@ -63,7 +63,7 @@ import GHC.Core.InstEnv
    63 63
     import GHC.Core.TyCo.Rep (Type(..))
    
    64 64
     import GHC.Core.TyCo.Ppr (pprWithInvisibleBitsWhen, pprSourceTyCon,
    
    65 65
                               pprTyVars, pprWithTYPE, pprTyVar, pprTidiedType, pprForAll)
    
    66
    -import GHC.Core.PatSyn ( patSynName, pprPatSynType )
    
    66
    +import GHC.Core.PatSyn ( patSynName, pprPatSynType, PatSyn )
    
    67 67
     import GHC.Core.TyCo.Tidy
    
    68 68
     import GHC.Core.Predicate
    
    69 69
     import GHC.Core.Type
    
    ... ... @@ -90,7 +90,7 @@ import GHC.Types.DefaultEnv (ClassDefaults(ClassDefaults, cd_types, cd_provenanc
    90 90
     import GHC.Types.Error
    
    91 91
     import GHC.Types.Error.Codes
    
    92 92
     import GHC.Types.Hint
    
    93
    -import GHC.Types.Hint.Ppr ( pprSigLike ) -- & Outputable GhcHint
    
    93
    +import GHC.Types.Hint.Ppr ( pprSigLike )
    
    94 94
     import GHC.Types.Basic
    
    95 95
     import GHC.Types.Id
    
    96 96
     import GHC.Types.Id.Info ( RecSelParent(..) )
    
    ... ... @@ -129,6 +129,9 @@ import qualified GHC.LanguageExtensions as LangExt
    129 129
     
    
    130 130
     import GHC.Data.BooleanFormula (pprBooleanFormulaNice)
    
    131 131
     
    
    132
    +import Language.Haskell.Syntax.Basic (field_label, FieldLabelString (..))
    
    133
    +
    
    134
    +import Control.Monad (guard)
    
    132 135
     import qualified Data.Semigroup as S
    
    133 136
     import Data.List.NonEmpty (NonEmpty(..))
    
    134 137
     import qualified Data.List.NonEmpty as NE
    
    ... ... @@ -4114,7 +4117,13 @@ pprTcSolverReportMsg ctxt (UnboundImplicitParams (item :| items)) =
    4114 4117
                 sep [ text "Unbound implicit parameter" <> plural preds
    
    4115 4118
                     , nest 2 (pprParendTheta preds) ]
    
    4116 4119
          else
    
    4117
    -        let mismatch = CouldNotDeduce givens (item :| items) Nothing
    
    4120
    +        let mismatch =
    
    4121
    +              CouldNotDeduce
    
    4122
    +                { cnd_user_givens   = givens
    
    4123
    +                , cnd_wanted        = item :| items
    
    4124
    +                , cnd_ea            = Nothing
    
    4125
    +                , cnd_noBuiltin_msg = Nothing
    
    4126
    +                }
    
    4118 4127
                 invis_bits = mismatchInvisibleBits mismatch
    
    4119 4128
                 ppr_msg = pprMismatchMsg ctxt mismatch
    
    4120 4129
             in
    
    ... ... @@ -4127,7 +4136,7 @@ pprTcSolverReportMsg _ (AmbiguityPreventsSolvingCt item ambigs) =
    4127 4136
       text "prevents the constraint" <+> quotes (pprParendType $ errorItemPred item)
    
    4128 4137
       <+> text "from being solved."
    
    4129 4138
     pprTcSolverReportMsg ctxt@(CEC {cec_encl = implics})
    
    4130
    -  (CannotResolveInstance item unifiers candidates rel_binds)
    
    4139
    +  (CannotResolveInstance item unifiers candidates rel_binds mb_HasField_msg)
    
    4131 4140
       = pprWithInvisibleBits invis_bits $
    
    4132 4141
         vcat
    
    4133 4142
           [ no_inst_msg
    
    ... ... @@ -4171,10 +4180,10 @@ pprTcSolverReportMsg ctxt@(CEC {cec_encl = implics})
    4171 4180
           | lead_with_ambig
    
    4172 4181
           = (Set.empty, pprTcSolverReportMsg ctxt $ AmbiguityPreventsSolvingCt item (ambig_kvs, ambig_tvs))
    
    4173 4182
           | otherwise
    
    4174
    -      = let mismatch = CouldNotDeduce useful_givens (item :| []) Nothing
    
    4183
    +      = let mismatch = CouldNotDeduce useful_givens (item :| []) Nothing mb_HasField_msg
    
    4175 4184
             in
    
    4176 4185
               ( mismatchInvisibleBits mismatch
    
    4177
    -          , pprMismatchMsg ctxt $ CouldNotDeduce useful_givens (item :| []) Nothing
    
    4186
    +          , pprMismatchMsg ctxt mismatch
    
    4178 4187
               )
    
    4179 4188
     
    
    4180 4189
         -- Report "potential instances" only when the constraint arises
    
    ... ... @@ -4202,6 +4211,9 @@ pprTcSolverReportMsg ctxt@(CEC {cec_encl = implics})
    4202 4211
           | otherwise = Nothing
    
    4203 4212
     
    
    4204 4213
         extra_note
    
    4214
    +      | Just {} <- mb_HasField_msg
    
    4215
    +      = empty
    
    4216
    +
    
    4205 4217
           -- Flag up partially applied uses of (->)
    
    4206 4218
           | any isFunTy (filterOutInvisibleTypes (classTyCon clas) tys)
    
    4207 4219
           = text "(maybe you haven't applied a function to enough arguments?)"
    
    ... ... @@ -4417,10 +4429,10 @@ mismatchInvisibleBits
    4417 4429
                       , teq_mismatch_ty1      = ty1
    
    4418 4430
                       , teq_mismatch_ty2      = ty2 })
    
    4419 4431
       = shouldPprWithInvisibleBits ty1 ty2 (errorItemOrigin item)
    
    4420
    -mismatchInvisibleBits (CouldNotDeduce { cnd_extra = mb_extra })
    
    4421
    -  = case mb_extra of
    
    4432
    +mismatchInvisibleBits (CouldNotDeduce { cnd_ea = mb_ea })
    
    4433
    +  = case mb_ea of
    
    4422 4434
           Nothing -> Set.empty
    
    4423
    -      Just (CND_Extra _ ty1 ty2) ->
    
    4435
    +      Just (CND_ExpectedActual _ ty1 ty2) ->
    
    4424 4436
             mayLookIdentical ty1 ty2
    
    4425 4437
     
    
    4426 4438
     -- | Turn a 'MismatchMsg' into an 'SDoc'.
    
    ... ... @@ -4612,9 +4624,14 @@ pprMismatchMsg ctxt
    4612 4624
     
    
    4613 4625
         starts_with_vowel (c:_) = c `elem` ("AEIOU" :: String)
    
    4614 4626
         starts_with_vowel []    = False
    
    4615
    -
    
    4616
    -pprMismatchMsg ctxt (CouldNotDeduce useful_givens (item :| others) mb_extra)
    
    4627
    +pprMismatchMsg ctxt
    
    4628
    +  (CouldNotDeduce { cnd_user_givens = useful_givens
    
    4629
    +                  , cnd_wanted = item :| others
    
    4630
    +                  , cnd_ea = mb_ea
    
    4631
    +                  , cnd_noBuiltin_msg = mb_NoBuiltin_msg
    
    4632
    +                  })
    
    4617 4633
       = vcat [ main_msg
    
    4634
    +         , maybe empty pprNoBuiltinInstanceMsg mb_NoBuiltin_msg
    
    4618 4635
              , pprQCOriginExtra item
    
    4619 4636
              , ea_supplementary ]
    
    4620 4637
       where
    
    ... ... @@ -4623,9 +4640,10 @@ pprMismatchMsg ctxt (CouldNotDeduce useful_givens (item :| others) mb_extra)
    4623 4640
           | otherwise          = vcat ( addArising ct_loc no_deduce_msg
    
    4624 4641
                                       : pp_from_givens useful_givens)
    
    4625 4642
     
    
    4626
    -    ea_supplementary = case mb_extra of
    
    4627
    -      Nothing                        -> empty
    
    4628
    -      Just (CND_Extra level ty1 ty2) -> mk_supplementary_ea_msg ctxt level ty1 ty2 orig
    
    4643
    +    ea_supplementary = case mb_ea of
    
    4644
    +      Nothing -> empty
    
    4645
    +      Just (CND_ExpectedActual level ty1 ty2) ->
    
    4646
    +        mk_supplementary_ea_msg ctxt level ty1 ty2 orig
    
    4629 4647
     
    
    4630 4648
         ct_loc = errorItemCtLoc item
    
    4631 4649
         orig   = ctLocOrigin ct_loc
    
    ... ... @@ -5022,6 +5040,87 @@ pprCoercibleMsg (OutOfScopeNewtypeConstructor tc dc) =
    5022 5040
         2 (sep [ text "of newtype" <+> quotes (pprSourceTyCon tc)
    
    5023 5041
                , text "is not in scope" ])
    
    5024 5042
     
    
    5043
    +pprNoBuiltinInstanceMsg :: NoBuiltinInstanceMsg -> SDoc
    
    5044
    +pprNoBuiltinInstanceMsg = \case
    
    5045
    +  NoBuiltinHasFieldMsg msg -> pprHasFieldMsg msg
    
    5046
    +
    
    5047
    +pprHasFieldMsg :: HasFieldMsg -> SDoc
    
    5048
    +pprHasFieldMsg = \case
    
    5049
    +  NotALiteralFieldName ty ->
    
    5050
    +    text "NB:" <+> quotes (ppr ty) <+> what
    
    5051
    +      where
    
    5052
    +        what
    
    5053
    +          | Just {} <- getCastedTyVar_maybe ty
    
    5054
    +          = text "is a type variable, not a string literal."
    
    5055
    +          | otherwise
    
    5056
    +          = text "is not a string literal."
    
    5057
    +  NotARecordType ty ->
    
    5058
    +    text "NB:" <+> quotes (ppr ty) <+> text "is not a record type."
    
    5059
    +  OutOfScopeField tc fld _import_suggs ->
    
    5060
    +    text "NB: the record field" <+> quotes (ppr fld) <+> text "of" <+> quotes (ppr tc) <+> text "is out of scope."
    
    5061
    +  FieldTooFancy tc fld rea ->
    
    5062
    +    case rea of
    
    5063
    +      FieldHasExistential ->
    
    5064
    +        text "NB: the record field" <+> quotes (ppr fld) <+> text "of" <+> quotes (ppr tc) <+> text "contains existential variables."
    
    5065
    +      FieldHasForAlls ->
    
    5066
    +        text "NB: the field type of the record field" <+> quotes (ppr fld) <+> text "of" <+> quotes (ppr tc) <+> text "is not a mono-type."
    
    5067
    +  CustomHasField custom_hasField ->
    
    5068
    +    text "NB:" <+> quotes (ppr custom_hasField) <+> text "is not the built-in"
    
    5069
    +      <+> quotes (ppr hasFieldClassName) <+> text "class."
    
    5070
    +  SuggestSimilarFields (Just (tc, rep_tc)) fld suggs pat_syns _imp_suggs ->
    
    5071
    +    vcat
    
    5072
    +      [   text "NB:" <+> quotes (ppr tc)
    
    5073
    +      <+> text "does not have a record field named"
    
    5074
    +      <+> quotes (ppr fld) <> dot
    
    5075
    +      , pprHasFieldPatSynMsg fld pat_syns
    
    5076
    +      , pprSameNameOtherTyCons (mapMaybe same_name_diff_tc suggs)
    
    5077
    +        -- NB: The actual suggestions are dealt with by
    
    5078
    +        -- GHC.Tc.Errors.hasFieldMsgHints. The logic here just covers
    
    5079
    +        -- information for which there is no actionable hint.
    
    5080
    +      ]
    
    5081
    +    where
    
    5082
    +      same_name_diff_tc (rep_tc', fld') = do
    
    5083
    +        let occ = case fld' of
    
    5084
    +                     SimilarName n -> getOccFS n
    
    5085
    +                     SimilarRdrName n _ _ -> occNameFS $ rdrNameOcc n
    
    5086
    +        guard $
    
    5087
    +          rep_tc' /= rep_tc
    
    5088
    +            &&
    
    5089
    +          (fld == FieldLabelString occ)
    
    5090
    +        return rep_tc'
    
    5091
    +  SuggestSimilarFields Nothing fld _suggs pat_syns _imp_suggs ->
    
    5092
    +    pprHasFieldPatSynMsg fld pat_syns
    
    5093
    +    -- Most of the error message only makes sense when we know the TyCon.
    
    5094
    +    -- In this "unknown TyCon" case, we only have:
    
    5095
    +    --   - the "PatSyns don't give HasField instances" message
    
    5096
    +    --   - the hints, which are handled separately (see 'hasFieldMsgHints').
    
    5097
    +
    
    5098
    +pprSameNameOtherTyCons :: [TyCon] -> SDoc
    
    5099
    +pprSameNameOtherTyCons [] = empty
    
    5100
    +pprSameNameOtherTyCons tcs =
    
    5101
    +  other_types_have <+> text "a field of this name:"
    
    5102
    +    <+> pprWithCommas (quotes . ppr) tcs <> dot
    
    5103
    +  where
    
    5104
    +    other_types_have :: SDoc
    
    5105
    +    other_types_have = case tcs of
    
    5106
    +      _:_:_ -> "Other types have"
    
    5107
    +      _     -> "Another type has"
    
    5108
    +
    
    5109
    +pprHasFieldPatSynMsg :: FieldLabelString -> [(PatSyn, SimilarName)] -> SDoc
    
    5110
    +pprHasFieldPatSynMsg fld pat_syns =
    
    5111
    +  if any same_name pat_syns
    
    5112
    +  then
    
    5113
    +    text "Pattern synonym record fields do not contribute"
    
    5114
    +      <+> quotes (ppr hasFieldClassName) <+> text "instances."
    
    5115
    +  else empty
    
    5116
    +  where
    
    5117
    +    same_name (_,nm) =
    
    5118
    +      let occ = case nm of
    
    5119
    +                  SimilarName n -> getOccFS n
    
    5120
    +                  SimilarRdrName n _ _ -> occNameFS $ rdrNameOcc n
    
    5121
    +      in
    
    5122
    +        occ == field_label fld
    
    5123
    +
    
    5025 5124
     pprWhenMatching :: SolverReportErrCtxt -> WhenMatching -> SDoc
    
    5026 5125
     pprWhenMatching ctxt (WhenMatching cty1 cty2 sub_o mb_sub_t_or_k) =
    
    5027 5126
       sdocOption sdocPrintExplicitCoercions $ \printExplicitCoercions ->
    
    ... ... @@ -5247,8 +5346,8 @@ tcSolverReportMsgHints ctxt = \case
    5247 5346
         -> noHints
    
    5248 5347
       AmbiguityPreventsSolvingCt {}
    
    5249 5348
         -> noHints
    
    5250
    -  CannotResolveInstance {}
    
    5251
    -    -> noHints
    
    5349
    +  CannotResolveInstance { cannotResolve_noBuiltinMsg = mb_noBuiltin }
    
    5350
    +    -> maybe noHints noBuiltinInstanceHints mb_noBuiltin
    
    5252 5351
       OverlappingInstances {}
    
    5253 5352
         -> noHints
    
    5254 5353
       UnsafeOverlap {}
    
    ... ... @@ -5256,22 +5355,66 @@ tcSolverReportMsgHints ctxt = \case
    5256 5355
       MultiplicityCoercionsNotSupported {}
    
    5257 5356
        -> noHints
    
    5258 5357
     
    
    5358
    +noBuiltinInstanceHints :: NoBuiltinInstanceMsg -> [GhcHint]
    
    5359
    +noBuiltinInstanceHints = \case
    
    5360
    +  NoBuiltinHasFieldMsg noHasFieldMsg -> hasFieldMsgHints noHasFieldMsg
    
    5361
    +
    
    5362
    +hasFieldMsgHints :: HasFieldMsg -> [GhcHint]
    
    5363
    +hasFieldMsgHints = \case
    
    5364
    +  NotALiteralFieldName {} -> noHints
    
    5365
    +  NotARecordType {}       -> noHints
    
    5366
    +  FieldTooFancy {}        -> noHints
    
    5367
    +  SuggestSimilarFields mb_orig_tc orig_fld suggs _patsyns imp_suggs ->
    
    5368
    +    map (ImportSuggestion fld_occ) imp_suggs ++ similar_suggs
    
    5369
    +    where
    
    5370
    +      fld_occ = mkVarOccFS $ field_label orig_fld
    
    5371
    +      similar_suggs =
    
    5372
    +        case NE.nonEmpty $ filter different_name suggs of
    
    5373
    +          Nothing -> noHints
    
    5374
    +          Just neSuggs ->
    
    5375
    +            case mb_orig_tc of
    
    5376
    +              Just (orig_tc, orig_rep_tc) ->
    
    5377
    +                -- We know the parent TyCon
    
    5378
    +                [SuggestSimilarSelectors orig_tc orig_rep_tc orig_fld neSuggs]
    
    5379
    +              Nothing ->
    
    5380
    +                -- We don't know the parent TyCon
    
    5381
    +                [ SuggestSimilarNames
    
    5382
    +                    (mkRdrUnqual fld_occ)
    
    5383
    +                    (fmap snd neSuggs)
    
    5384
    +                ]
    
    5385
    +      different_name ( _, nm ) =
    
    5386
    +        let occ = case nm of
    
    5387
    +                    SimilarName n -> getOccFS n
    
    5388
    +                    SimilarRdrName n _ _ -> occNameFS $ rdrNameOcc n
    
    5389
    +        in
    
    5390
    +          orig_fld /= FieldLabelString occ
    
    5391
    +  OutOfScopeField _tc fld import_suggs ->
    
    5392
    +    map (ImportSuggestion (nameOccName $ flSelector fld)) import_suggs
    
    5393
    +  CustomHasField {} -> noHints
    
    5394
    +
    
    5259 5395
     mismatchMsgHints :: SolverReportErrCtxt -> MismatchMsg -> [GhcHint]
    
    5260 5396
     mismatchMsgHints ctxt msg =
    
    5397
    +  mismatchMsgHasFieldHints msg ++
    
    5261 5398
       maybeToList [ hint | (exp,act) <- mismatchMsg_ExpectedActuals msg
    
    5262 5399
                          , hint <- suggestAddSig ctxt exp act ]
    
    5263 5400
     
    
    5401
    +mismatchMsgHasFieldHints :: MismatchMsg -> [GhcHint]
    
    5402
    +mismatchMsgHasFieldHints
    
    5403
    +  (CouldNotDeduce { cnd_noBuiltin_msg = mb_noBuiltin }) =
    
    5404
    +    maybe noHints noBuiltinInstanceHints mb_noBuiltin
    
    5405
    +mismatchMsgHasFieldHints (BasicMismatch{}) = []
    
    5406
    +mismatchMsgHasFieldHints (TypeEqMismatch{}) = []
    
    5407
    +
    
    5264 5408
     mismatchMsg_ExpectedActuals :: MismatchMsg -> Maybe (Type, Type)
    
    5265 5409
     mismatchMsg_ExpectedActuals = \case
    
    5266 5410
       BasicMismatch { mismatch_ty1 = exp, mismatch_ty2 = act } ->
    
    5267 5411
         Just (exp, act)
    
    5268 5412
       TypeEqMismatch { teq_mismatch_expected = exp, teq_mismatch_actual = act } ->
    
    5269 5413
         Just (exp,act)
    
    5270
    -  CouldNotDeduce { cnd_extra = cnd_extra }
    
    5271
    -    | Just (CND_Extra _ exp act) <- cnd_extra
    
    5272
    -    -> Just (exp, act)
    
    5273
    -    | otherwise
    
    5274
    -    -> Nothing
    
    5414
    +  CouldNotDeduce { cnd_ea = mb_ea } ->
    
    5415
    +    case mb_ea of
    
    5416
    +      Just (CND_ExpectedActual _ exp act) -> Just (exp, act)
    
    5417
    +      Nothing -> Nothing
    
    5275 5418
     
    
    5276 5419
     cannotUnifyVariableHints :: CannotUnifyVariableReason -> [GhcHint]
    
    5277 5420
     cannotUnifyVariableHints = \case
    

  • compiler/GHC/Tc/Errors/Types.hs
    ... ... @@ -72,7 +72,7 @@ module GHC.Tc.Errors.Types (
    72 72
       , ExpectedActualInfo(..)
    
    73 73
       , TyVarInfo(..), SameOccInfo(..)
    
    74 74
       , AmbiguityInfo(..)
    
    75
    -  , CND_Extra(..)
    
    75
    +  , CND_ExpectedActual(..)
    
    76 76
       , FitsMbSuppressed(..)
    
    77 77
       , ValidHoleFits(..), noValidHoleFits
    
    78 78
       , HoleFitDispConfig(..)
    
    ... ... @@ -86,6 +86,9 @@ module GHC.Tc.Errors.Types (
    86 86
       , lookingForSubordinate
    
    87 87
       , HoleError(..)
    
    88 88
       , CoercibleMsg(..)
    
    89
    +  , NoBuiltinInstanceMsg(..)
    
    90
    +  , HasFieldMsg(..)
    
    91
    +  , TooFancyField(..)
    
    89 92
       , PotentialInstances(..)
    
    90 93
       , UnsupportedCallConvention(..)
    
    91 94
       , ExpectedBackends
    
    ... ... @@ -200,7 +203,7 @@ import GHC.Tc.Utils.TcType (TcType, TcSigmaType, TcPredType,
    200 203
     import GHC.Types.Basic
    
    201 204
     import GHC.Types.Error
    
    202 205
     import GHC.Types.Avail
    
    203
    -import GHC.Types.Hint (UntickedPromotedThing(..), AssumedDerivingStrategy(..), SigLike)
    
    206
    +import GHC.Types.Hint
    
    204 207
     import GHC.Types.ForeignCall (CLabelString)
    
    205 208
     import GHC.Types.Id.Info ( RecSelParent(..) )
    
    206 209
     import GHC.Types.Name (NamedThing(..), Name, OccName, getSrcLoc, getSrcSpan)
    
    ... ... @@ -5615,6 +5618,7 @@ data TcSolverReportMsg
    5615 5618
         , cannotResolve_unifiers     :: [ClsInst]
    
    5616 5619
         , cannotResolve_candidates   :: [ClsInst]
    
    5617 5620
         , cannotResolve_relBinds     :: RelevantBindings
    
    5621
    +    , cannotResolve_noBuiltinMsg :: Maybe NoBuiltinInstanceMsg
    
    5618 5622
         }
    
    5619 5623
     
    
    5620 5624
       -- | Could not solve a constraint using available instances
    
    ... ... @@ -5675,15 +5679,20 @@ data MismatchMsg
    5675 5679
       -- Used for messages such as @"No instance for ..."@ and
    
    5676 5680
       -- @"Could not deduce ... from"@.
    
    5677 5681
       | CouldNotDeduce
    
    5678
    -     { cnd_user_givens :: [Implication]
    
    5682
    +     { cnd_user_givens   :: [Implication]
    
    5679 5683
             -- | The Wanted constraints we couldn't solve.
    
    5680 5684
             --
    
    5681 5685
             -- N.B.: the 'ErrorItem' at the head of the list has been tidied,
    
    5682 5686
             -- perhaps not the others.
    
    5683
    -     , cnd_wanted      :: NE.NonEmpty ErrorItem
    
    5687
    +     , cnd_wanted        :: NE.NonEmpty ErrorItem
    
    5684 5688
     
    
    5685
    -       -- | Some additional info consumed by 'mk_supplementary_ea_msg'.
    
    5686
    -     , cnd_extra       :: Maybe CND_Extra
    
    5689
    +       -- | Additional "expected/actual" information
    
    5690
    +       -- consumed by 'mk_supplementary_ea_msg'.
    
    5691
    +     , cnd_ea            :: Maybe CND_ExpectedActual
    
    5692
    +
    
    5693
    +       -- | Additional message relating to unsolved constraints for
    
    5694
    +       -- typeclasses which have built-in instances.
    
    5695
    +     , cnd_noBuiltin_msg :: Maybe NoBuiltinInstanceMsg
    
    5687 5696
          }
    
    5688 5697
       deriving Generic
    
    5689 5698
     
    
    ... ... @@ -5753,7 +5762,7 @@ mkPlainMismatchMsg msg
    5753 5762
     
    
    5754 5763
     -- | Additional information to be given in a 'CouldNotDeduce' message,
    
    5755 5764
     -- which is then passed on to 'mk_supplementary_ea_msg'.
    
    5756
    -data CND_Extra = CND_Extra TypeOrKind Type Type
    
    5765
    +data CND_ExpectedActual = CND_ExpectedActual TypeOrKind Type Type
    
    5757 5766
     
    
    5758 5767
     -- | A cue to print out information about type variables,
    
    5759 5768
     -- e.g. where they were bound, when there is a mismatch @tv1 ~ ty2@.
    
    ... ... @@ -5967,6 +5976,48 @@ data CoercibleMsg
    5967 5976
       -- Test cases: TcCoercibleFail.
    
    5968 5977
       | OutOfScopeNewtypeConstructor TyCon DataCon
    
    5969 5978
     
    
    5979
    +-- | Explains why GHC wasn't able to provide a built-in instance for
    
    5980
    +-- a particular class.
    
    5981
    +data NoBuiltinInstanceMsg
    
    5982
    +  = NoBuiltinHasFieldMsg HasFieldMsg
    
    5983
    +
    
    5984
    +  -- Other useful constructors might be:
    
    5985
    +  -- NoBuiltinTypeableMsg  -- explains polykinded Typeable restrictions
    
    5986
    +  -- NoBuiltinDataToTagMsg -- see conditions in Note [DataToTag overview]
    
    5987
    +  -- NoBuiltinWithDictMsg  -- see Note [withDict]
    
    5988
    +
    
    5989
    +-- | Explains why GHC wasn't able to provide a built-in 'HasField' instance
    
    5990
    +-- for the given types.
    
    5991
    +data HasFieldMsg
    
    5992
    +  -- | The field is not a literal field name, e.g. @HasField x u v@ where @x@
    
    5993
    +  -- is a type variable.
    
    5994
    +  = NotALiteralFieldName Type
    
    5995
    +  -- | The type we are selecting from is not a record type,
    
    5996
    +  -- e.g. @HasField "fld" Int fld@.
    
    5997
    +  | NotARecordType Type
    
    5998
    +  -- | The field is out of scope.
    
    5999
    +  | OutOfScopeField TyCon FieldLabel [ImportSuggestion]
    
    6000
    +  -- | The field has a type which means that GHC cannot solve
    
    6001
    +  -- a 'HasField' constraint for it.
    
    6002
    +  | FieldTooFancy TyCon FieldLabelString TooFancyField
    
    6003
    +  -- | No such field, but the field is perhaps mis-spelled;
    
    6004
    +  -- here are some suggestions.
    
    6005
    +  | SuggestSimilarFields
    
    6006
    +      (Maybe (TyCon, TyCon)) -- ^ (optional) desired parent (tc and rep_tc)
    
    6007
    +      FieldLabelString       -- ^ field name
    
    6008
    +      [(TyCon, SimilarName)]         -- ^ suggestions (for this 'TyCon' or other 'TyCon's)
    
    6009
    +      [(PatSyn, SimilarName)]       -- ^ pattern synonyms with similarly named fields
    
    6010
    +      [ImportSuggestion]     -- ^ import suggestions
    
    6011
    +
    
    6012
    +  -- | Using -XRebindableSyntax and a different 'HasField'.
    
    6013
    +  | CustomHasField TyCon -- ^ the custom HasField TyCon
    
    6014
    +
    
    6015
    +-- | Why is a record field "too fancy" for GHC to be able to properly
    
    6016
    +-- solve a 'HasField' constraint?
    
    6017
    +data TooFancyField
    
    6018
    +  = FieldHasExistential
    
    6019
    +  | FieldHasForAlls
    
    6020
    +
    
    5970 6021
     -- | Explain a problem with an import.
    
    5971 6022
     data ImportError
    
    5972 6023
       -- | Couldn't find a module with the requested name.
    

  • compiler/GHC/Tc/Instance/Class.hs
    ... ... @@ -1247,6 +1247,11 @@ matchHasField dflags short_cut clas tys mb_ct_loc
    1247 1247
                          -- The selector must not be "naughty" (i.e. the field
    
    1248 1248
                          -- cannot have an existentially quantified type),
    
    1249 1249
                          -- and it must not be higher-rank.
    
    1250
    +                     --
    
    1251
    +                     -- See also 'GHC.Tc.Errors.hasFieldInfo_maybe', which is
    
    1252
    +                     -- responsible for the error messages in cases of unsolved
    
    1253
    +                     -- HasField constraints when the field type runs afoul
    
    1254
    +                     -- of these conditions.
    
    1250 1255
                        ; if (isNaughtyRecordSelector sel_id) || not (isTauTy sel_ty)
    
    1251 1256
                          then try_user_instances
    
    1252 1257
                          else
    
    ... ... @@ -1306,6 +1311,11 @@ lookupHasFieldLabel
    1306 1311
     -- A complication is that `T` might be a data family, so we need to
    
    1307 1312
     -- look it up in the `fam_envs` to find its representation tycon.
    
    1308 1313
     lookupHasFieldLabel fam_inst_envs rdr_env arg_tys
    
    1314
    +
    
    1315
    +  -- NB: if you edit this function, you might also want to update
    
    1316
    +  -- GHC.Tc.Errors.hasfieldInfo_maybe which is responsible for error messages
    
    1317
    +  -- when GHC /does not/ solve a 'HasField' constraint.
    
    1318
    +
    
    1309 1319
       |  -- We are matching HasField {k} {r_rep} {a_rep} x r a...
    
    1310 1320
         (_k : _rec_rep : _fld_rep : x_ty : rec_ty : fld_ty : _) <- arg_tys
    
    1311 1321
         -- x should be a literal string
    

  • compiler/GHC/Tc/TyCl/PatSyn.hs
    ... ... @@ -136,7 +136,7 @@ tcInferPatSynDecl (PSB { psb_id = lname@(L _ name), psb_args = details
    136 136
            ; let (arg_names, is_infix) = collectPatSynArgInfo details
    
    137 137
            ; (tclvl, wanted, ((lpat', args), pat_ty))
    
    138 138
                 <- pushLevelAndCaptureConstraints      $
    
    139
    -               tcInferPat FRRPatSynArg PatSyn lpat $
    
    139
    +               tcInferPat FRRPatSynArg PatSynCtx lpat $
    
    140 140
                    mapM tcLookupId arg_names
    
    141 141
     
    
    142 142
            ; let (ex_tvs, prov_dicts) = tcCollectEx lpat'
    
    ... ... @@ -421,7 +421,7 @@ tcCheckPatSynDecl psb@PSB{ psb_id = lname@(L _ name), psb_args = details
    421 421
                assertPpr (equalLength arg_names arg_tys) (ppr name $$ ppr arg_names $$ ppr arg_tys) $
    
    422 422
                pushLevelAndCaptureConstraints   $
    
    423 423
                tcExtendNameTyVarEnv univ_tv_prs $
    
    424
    -           tcCheckPat PatSyn lpat (unrestricted skol_pat_ty)   $
    
    424
    +           tcCheckPat PatSynCtx lpat (unrestricted skol_pat_ty)   $
    
    425 425
                do { let in_scope    = mkInScopeSetList skol_univ_tvs
    
    426 426
                         empty_subst = mkEmptySubst in_scope
    
    427 427
                   ; (inst_subst, ex_tvs') <- mapAccumLM newMetaTyVarX empty_subst skol_ex_tvs
    
    ... ... @@ -843,7 +843,7 @@ tcPatSynMatcher (L loc ps_name) lpat prag_fn
    843 843
                  gen = Generated OtherExpansion SkipPmc
    
    844 844
                  body = mkLHsWrap (mkWpLet req_ev_binds) $
    
    845 845
                         L (getLoc lpat) $
    
    846
    -                    HsCase PatSyn (nlHsVar scrutinee) $
    
    846
    +                    HsCase PatSynCtx (nlHsVar scrutinee) $
    
    847 847
                         MG{ mg_alts = L (l2l $ getLoc lpat) cases
    
    848 848
                           , mg_ext = MatchGroupTc [unrestricted pat_ty] res_ty gen
    
    849 849
                           }
    

  • compiler/GHC/Tc/TyCl/Utils.hs
    ... ... @@ -21,7 +21,7 @@ module GHC.Tc.TyCl.Utils(
    21 21
             addTyConsToGblEnv, mkDefaultMethodType,
    
    22 22
     
    
    23 23
             -- * Record selectors
    
    24
    -        tcRecSelBinds, mkRecSelBinds, mkOneRecordSelector
    
    24
    +        tcRecSelBinds, mkRecSelBinds, mkOneRecordSelector,
    
    25 25
         ) where
    
    26 26
     
    
    27 27
     import GHC.Prelude
    
    ... ... @@ -899,7 +899,7 @@ mkOneRecordSelector all_cons idDetails fl has_sel
    899 899
     
    
    900 900
     
    
    901 901
         -- Selector type; Note [Polymorphic selectors]
    
    902
    -    (univ_tvs, _, _, _, req_theta, _, data_ty) = conLikeFullSig con1
    
    902
    +    (_, _, _, _, req_theta, _, data_ty) = conLikeFullSig con1
    
    903 903
     
    
    904 904
         field_ty     = conLikeFieldType con1 lbl
    
    905 905
         field_ty_tvs = tyCoVarsOfType field_ty
    
    ... ... @@ -909,17 +909,13 @@ mkOneRecordSelector all_cons idDetails fl has_sel
    909 909
                        conLikeUserTyVarBinders con1
    
    910 910
     
    
    911 911
         -- is_naughty: see Note [Naughty record selectors]
    
    912
    -    is_naughty = not ok_scoping || no_selectors
    
    913
    -    ok_scoping = case con1 of
    
    914
    -                   RealDataCon {} -> field_ty_tvs `subVarSet` data_ty_tvs
    
    915
    -                   PatSynCon {}   -> field_ty_tvs `subVarSet` mkVarSet univ_tvs
    
    916
    -       -- In the PatSynCon case, the selector type is (data_ty -> field_ty), but
    
    917
    -       -- fvs(data_ty) are all universals (see Note [Pattern synonym result type] in
    
    918
    -       -- GHC.Core.PatSyn, so no need to check them.
    
    919
    -
    
    920
    -    no_selectors   = has_sel == NoFieldSelectors  -- No field selectors => all are naughty
    
    921
    -                                                  -- thus suppressing making a binding
    
    922
    -                                                  -- A slight hack!
    
    912
    +    is_naughty = isExistentialRecordField field_ty con1 || no_selectors
    
    913
    +
    
    914
    +    no_selectors   = has_sel == NoFieldSelectors
    
    915
    +      -- For PatternSynonyms with -XNoFieldSelectors, pretend the fields
    
    916
    +      -- are naughty record selectors to suppress making a binding.
    
    917
    +      --
    
    918
    +      -- See Note [NoFieldSelectors and naughty record selectors]
    
    923 919
     
    
    924 920
         sel_ty | is_naughty = unitTy  -- See Note [Naughty record selectors]
    
    925 921
                | otherwise  = mkForAllTys sel_tvbs $
    

  • compiler/GHC/Tc/Types/Origin.hs
    ... ... @@ -524,7 +524,7 @@ data CtOrigin
    524 524
       ----------- Below here, all are Origins for Wanted constraints ------------
    
    525 525
     
    
    526 526
       | OccurrenceOf Name          -- ^ Occurrence of an overloaded identifier
    
    527
    -  | OccurrenceOfRecSel RdrName -- ^ Occurrence of a record selector
    
    527
    +  | OccurrenceOfRecSel (LocatedN RdrName) -- ^ Occurrence of a record selector
    
    528 528
       | AppOrigin                  -- ^ An application of some kind
    
    529 529
     
    
    530 530
       | SpecPragOrigin UserTypeCtxt    -- ^ Specialisation pragma for
    
    ... ... @@ -558,7 +558,10 @@ data CtOrigin
    558 558
                             -- IMPORTANT: These constraints will never cause errors;
    
    559 559
                             -- See Note [Constraints to ignore] in GHC.Tc.Errors
    
    560 560
       | SectionOrigin
    
    561
    -  | GetFieldOrigin FastString
    
    561
    +  | GetFieldOrigin (LocatedN FastString)
    
    562
    +
    
    563
    +  -- | A overloaded record field projection like @.fld@ or @.fld1.fld2.fld@.
    
    564
    +  | RecordFieldProjectionOrigin (FieldLabelStrings GhcRn)
    
    562 565
       | TupleOrigin         -- (..,..)
    
    563 566
       | ExprSigOrigin       -- e :: ty
    
    564 567
       | PatSigOrigin        -- p :: ty
    
    ... ... @@ -566,7 +569,7 @@ data CtOrigin
    566 569
       | ProvCtxtOrigin      -- The "provided" context of a pattern synonym signature
    
    567 570
             (PatSynBind GhcRn GhcRn) -- Information about the pattern synonym, in
    
    568 571
                                      -- particular the name and the right-hand side
    
    569
    -  | RecordUpdOrigin
    
    572
    +  | RecordUpdOrigin (LHsRecUpdFields GhcRn)
    
    570 573
       | ViewPatOrigin
    
    571 574
     
    
    572 575
       -- | 'ScOrigin' is used only for the Wanted constraints for the
    
    ... ... @@ -737,7 +740,7 @@ lexprCtOrigin (L _ e) = exprCtOrigin e
    737 740
     
    
    738 741
     exprCtOrigin :: HsExpr GhcRn -> CtOrigin
    
    739 742
     exprCtOrigin (HsVar _ (L _ (WithUserRdr _ name))) = OccurrenceOf name
    
    740
    -exprCtOrigin (HsGetField _ _ (L _ f)) = GetFieldOrigin (field_label $ unLoc $ dfoLabel f)
    
    743
    +exprCtOrigin (HsGetField _ _ (L _ f)) = GetFieldOrigin (fmap field_label $ dfoLabel f)
    
    741 744
     exprCtOrigin (HsOverLabel _ l)  = OverLabelOrigin l
    
    742 745
     exprCtOrigin (ExplicitList {})    = ListOrigin
    
    743 746
     exprCtOrigin (HsIPVar _ ip)       = IPOccOrigin ip
    
    ... ... @@ -749,9 +752,9 @@ exprCtOrigin (HsAppType _ e1 _) = lexprCtOrigin e1
    749 752
     exprCtOrigin (OpApp _ _ op _)     = lexprCtOrigin op
    
    750 753
     exprCtOrigin (NegApp _ e _)       = lexprCtOrigin e
    
    751 754
     exprCtOrigin (HsPar _ e)          = lexprCtOrigin e
    
    752
    -exprCtOrigin (HsProjection _ _)   = SectionOrigin
    
    753
    -exprCtOrigin (SectionL _ _ _)     = SectionOrigin
    
    754
    -exprCtOrigin (SectionR _ _ _)     = SectionOrigin
    
    755
    +exprCtOrigin (HsProjection _ p)   = RecordFieldProjectionOrigin (FieldLabelStrings $ fmap noLocA p)
    
    756
    +exprCtOrigin (SectionL {})        = SectionOrigin
    
    757
    +exprCtOrigin (SectionR {})        = SectionOrigin
    
    755 758
     exprCtOrigin (ExplicitTuple {})   = Shouldn'tHappenOrigin "explicit tuple"
    
    756 759
     exprCtOrigin ExplicitSum{}        = Shouldn'tHappenOrigin "explicit sum"
    
    757 760
     exprCtOrigin (HsCase _ _ matches) = matchesCtOrigin matches
    
    ... ... @@ -760,7 +763,7 @@ exprCtOrigin (HsMultiIf _ rhs) = lGRHSCtOrigin rhs
    760 763
     exprCtOrigin (HsLet _ _ e)       = lexprCtOrigin e
    
    761 764
     exprCtOrigin (HsDo {})           = DoOrigin
    
    762 765
     exprCtOrigin (RecordCon {})      = Shouldn'tHappenOrigin "record construction"
    
    763
    -exprCtOrigin (RecordUpd {})      = RecordUpdOrigin
    
    766
    +exprCtOrigin (RecordUpd _ _ flds)= RecordUpdOrigin flds
    
    764 767
     exprCtOrigin (ExprWithTySig {})  = ExprSigOrigin
    
    765 768
     exprCtOrigin (ArithSeq {})       = Shouldn'tHappenOrigin "arithmetic sequence"
    
    766 769
     exprCtOrigin (HsPragE _ _ e)     = lexprCtOrigin e
    
    ... ... @@ -779,7 +782,7 @@ exprCtOrigin (XExpr (ExpandedThingRn thing _)) | OrigExpr a <- thing = exprCtOri
    779 782
                                                    | OrigStmt _ <- thing = DoOrigin
    
    780 783
                                                    | OrigPat p  <- thing = DoPatOrigin p
    
    781 784
     exprCtOrigin (XExpr (PopErrCtxt {})) = Shouldn'tHappenOrigin "PopErrCtxt"
    
    782
    -exprCtOrigin (XExpr (HsRecSelRn f))  = OccurrenceOfRecSel (foExt f)
    
    785
    +exprCtOrigin (XExpr (HsRecSelRn f))  = OccurrenceOfRecSel $ L (getLoc $ foLabel f) (foExt f)
    
    783 786
     
    
    784 787
     -- | Extract a suitable CtOrigin from a MatchGroup
    
    785 788
     matchesCtOrigin :: MatchGroup GhcRn (LHsExpr GhcRn) -> CtOrigin
    
    ... ... @@ -937,7 +940,7 @@ ppr_br AppOrigin = text "an application"
    937 940
     ppr_br (IPOccOrigin name)    = hsep [text "a use of implicit parameter", quotes (ppr name)]
    
    938 941
     ppr_br (OverLabelOrigin l)   = hsep [text "the overloaded label"
    
    939 942
                                         ,quotes (char '#' <> ppr l)]
    
    940
    -ppr_br RecordUpdOrigin       = text "a record update"
    
    943
    +ppr_br (RecordUpdOrigin {})  = text "a record update"
    
    941 944
     ppr_br ExprSigOrigin         = text "an expression type signature"
    
    942 945
     ppr_br PatSigOrigin          = text "a pattern type signature"
    
    943 946
     ppr_br PatOrigin             = text "a pattern"
    
    ... ... @@ -945,6 +948,7 @@ ppr_br ViewPatOrigin = text "a view pattern"
    945 948
     ppr_br (LiteralOrigin lit)   = hsep [text "the literal", quotes (ppr lit)]
    
    946 949
     ppr_br (ArithSeqOrigin seq)  = hsep [text "the arithmetic sequence", quotes (ppr seq)]
    
    947 950
     ppr_br SectionOrigin         = text "an operator section"
    
    951
    +ppr_br (RecordFieldProjectionOrigin p) = text "the record selector" <+> quotes (ppr p)
    
    948 952
     ppr_br (GetFieldOrigin f)    = hsep [text "selecting the field", quotes (ppr f)]
    
    949 953
     ppr_br AssocFamPatOrigin     = text "the LHS of a family instance"
    
    950 954
     ppr_br TupleOrigin           = text "a tuple"
    

  • compiler/GHC/Types/Hint.hs
    ... ... @@ -42,12 +42,14 @@ import GHC.Core.TyCon (TyCon)
    42 42
     import GHC.Core.Type (Type)
    
    43 43
     import GHC.Types.Fixity (LexicalFixity(..))
    
    44 44
     import GHC.Types.Name (Name, NameSpace, OccName (occNameFS), isSymOcc, nameOccName)
    
    45
    -import GHC.Types.Name.Reader (RdrName (Unqual), ImpDeclSpec)
    
    45
    +import GHC.Types.Name.Reader (RdrName (Unqual), ImpDeclSpec, GlobalRdrElt)
    
    46 46
     import GHC.Types.SrcLoc (SrcSpan)
    
    47 47
     import GHC.Types.Basic (Activation, RuleName)
    
    48 48
     import GHC.Parser.Errors.Basic
    
    49 49
     import GHC.Utils.Outputable
    
    50
    -import GHC.Data.FastString (fsLit, FastString)
    
    50
    +import GHC.Data.FastString (fsLit)
    
    51
    +
    
    52
    +import Language.Haskell.Syntax.Basic (FieldLabelString)
    
    51 53
     
    
    52 54
     import Data.Typeable ( Typeable )
    
    53 55
     import Data.Map.Strict (Map)
    
    ... ... @@ -394,6 +396,12 @@ data GhcHint
    394 396
       -}
    
    395 397
       | SuggestSimilarNames RdrName (NE.NonEmpty SimilarName)
    
    396 398
     
    
    399
    +  {-| Suggest a similar record selector that the user might have meant.
    
    400
    +
    
    401
    +      Test case: T26480b.
    
    402
    +  -}
    
    403
    +  | SuggestSimilarSelectors TyCon TyCon FieldLabelString (NE.NonEmpty (TyCon, SimilarName))
    
    404
    +
    
    397 405
       {-| Remind the user that the field selector has been suppressed
    
    398 406
           because of -XNoFieldSelectors.
    
    399 407
     
    
    ... ... @@ -464,9 +472,6 @@ data GhcHint
    464 472
       {-| Suggest eta-reducing a type synonym used in the implementation
    
    465 473
           of abstract data. -}
    
    466 474
       | SuggestEtaReduceAbsDataTySyn TyCon
    
    467
    -  {-| Remind the user that there is no field of a type and name in the record,
    
    468
    -      constructors are in the usual order $x$, $r$, $a$ -}
    
    469
    -  | RemindRecordMissingField FastString Type Type
    
    470 475
       {-| Suggest binding the type variable on the LHS of the type declaration
    
    471 476
       -}
    
    472 477
       | SuggestBindTyVarOnLhs RdrName
    
    ... ... @@ -579,7 +584,7 @@ data HowInScope
    579 584
     
    
    580 585
     data SimilarName
    
    581 586
       = SimilarName Name
    
    582
    -  | SimilarRdrName RdrName (Maybe HowInScope)
    
    587
    +  | SimilarRdrName RdrName (Maybe GlobalRdrElt) (Maybe HowInScope)
    
    583 588
     
    
    584 589
     -- | Some kind of signature, such as a fixity signature, standalone
    
    585 590
     -- kind signature, COMPLETE pragma, role annotation, etc.
    

  • compiler/GHC/Types/Hint/Ppr.hs
    ... ... @@ -15,7 +15,7 @@ import GHC.Types.Hint
    15 15
     
    
    16 16
     import GHC.Core.FamInstEnv (FamFlavor(..))
    
    17 17
     import GHC.Core.TyCon
    
    18
    -import GHC.Core.TyCo.Rep     ( mkVisFunTyMany )
    
    18
    +import GHC.Hs.Binds (hsSigDoc)
    
    19 19
     import GHC.Hs.Expr ()   -- instance Outputable
    
    20 20
     import GHC.Types.Id
    
    21 21
     import GHC.Types.Name
    
    ... ... @@ -25,14 +25,16 @@ import GHC.Unit.Module.Imported (ImportedModsVal(..))
    25 25
     import GHC.Unit.Types
    
    26 26
     import GHC.Utils.Outputable
    
    27 27
     
    
    28
    +import qualified GHC.LanguageExtensions as LangExt
    
    29
    +
    
    28 30
     import GHC.Driver.Flags
    
    29 31
     
    
    32
    +import Language.Haskell.Syntax.Basic (FieldLabelString)
    
    33
    +
    
    34
    +import Data.List (partition)
    
    30 35
     import qualified Data.List.NonEmpty as NE
    
    31 36
     import qualified Data.Map.Strict as Map
    
    32 37
     
    
    33
    -import qualified GHC.LanguageExtensions as LangExt
    
    34
    -import GHC.Hs.Binds (hsSigDoc)
    
    35
    -
    
    36 38
     instance Outputable GhcHint where
    
    37 39
       ppr = \case
    
    38 40
         UnknownHint m
    
    ... ... @@ -198,7 +200,9 @@ instance Outputable GhcHint where
    198 200
                                   , nest 2 (pprWithCommas pp_item $ NE.toList similar_names) ]
    
    199 201
             where
    
    200 202
               tried_ns = occNameSpace $ rdrNameOcc tried_rdr_name
    
    201
    -          pp_item = pprSimilarName tried_ns
    
    203
    +          pp_item = pprSimilarName (Just tried_ns)
    
    204
    +    SuggestSimilarSelectors tc rep_tc fld suggs ->
    
    205
    +      pprSimilarFields tc rep_tc fld (NE.toList suggs)
    
    202 206
         RemindFieldSelectorSuppressed rdr_name parents
    
    203 207
           -> text "Notice that" <+> quotes (ppr rdr_name)
    
    204 208
              <+> text "is a field selector" <+> whose
    
    ... ... @@ -255,12 +259,6 @@ instance Outputable GhcHint where
    255 259
         SuggestEtaReduceAbsDataTySyn tc
    
    256 260
           -> text "If possible, eta-reduce the type synonym" <+> ppr_tc <+> text "so that it is nullary."
    
    257 261
             where ppr_tc = quotes (ppr $ tyConName tc)
    
    258
    -    RemindRecordMissingField x r a ->
    
    259
    -      text "NB: There is no field selector" <+> ppr_sel
    
    260
    -        <+> text "in scope for record type" <+> ppr_r
    
    261
    -      where ppr_sel = quotes (ftext x <+> dcolon <+> ppr_arr_r_a)
    
    262
    -            ppr_arr_r_a = ppr $ mkVisFunTyMany r a
    
    263
    -            ppr_r = quotes $ ppr r
    
    264 262
         SuggestBindTyVarOnLhs tv
    
    265 263
           -> text "Bind" <+> quotes (ppr tv) <+> text "on the LHS of the type declaration"
    
    266 264
         SuggestAnonymousWildcard
    
    ... ... @@ -405,10 +403,10 @@ pprImportSuggestion dc_occ (ImportDataCon { ies_suggest_import_from = Just mod
    405 403
         parens_sp d = parens (space <> d <> space)
    
    406 404
     
    
    407 405
     -- | Pretty-print a 'SimilarName'.
    
    408
    -pprSimilarName :: NameSpace -> SimilarName -> SDoc
    
    406
    +pprSimilarName :: Maybe NameSpace -> SimilarName -> SDoc
    
    409 407
     pprSimilarName _ (SimilarName name)
    
    410 408
       = quotes (ppr name) <+> parens (pprDefinedAt name)
    
    411
    -pprSimilarName tried_ns (SimilarRdrName rdr_name how_in_scope)
    
    409
    +pprSimilarName mb_tried_ns (SimilarRdrName rdr_name _gre_info how_in_scope)
    
    412 410
       = pp_ns rdr_name <+> quotes (ppr rdr_name) <+> loc
    
    413 411
       where
    
    414 412
         loc = case how_in_scope of
    
    ... ... @@ -421,8 +419,12 @@ pprSimilarName tried_ns (SimilarRdrName rdr_name how_in_scope)
    421 419
             ImportedBy is ->
    
    422 420
               parens (text "imported from" <+> ppr (moduleName $ is_mod is))
    
    423 421
         pp_ns :: RdrName -> SDoc
    
    424
    -    pp_ns rdr | ns /= tried_ns = pprNameSpace ns
    
    425
    -              | otherwise      = empty
    
    422
    +    pp_ns rdr
    
    423
    +      | Just tried_ns <- mb_tried_ns
    
    424
    +      , ns /= tried_ns
    
    425
    +      = pprNameSpace ns
    
    426
    +      | otherwise
    
    427
    +      = empty
    
    426 428
           where ns = rdrNameSpace rdr
    
    427 429
     
    
    428 430
     pprImpliedExtensions :: LangExt.Extension -> SDoc
    
    ... ... @@ -437,6 +439,34 @@ pprPrefixUnqual :: Name -> SDoc
    437 439
     pprPrefixUnqual name =
    
    438 440
       pprPrefixOcc (getOccName name)
    
    439 441
     
    
    442
    +pprSimilarFields :: TyCon -> TyCon -> FieldLabelString -> [(TyCon, SimilarName)] -> SDoc
    
    443
    +pprSimilarFields _tc rep_tc _fld suggs
    
    444
    +  | null suggs
    
    445
    +  = empty
    
    446
    +  -- There are similarly named fields for the right TyCon: report those first.
    
    447
    +  | same_tc_sugg1 : same_tc_rest <- same_tc
    
    448
    +  = case same_tc_rest of
    
    449
    +      [] ->
    
    450
    +        text "Perhaps use" <+> ppr_same_tc same_tc_sugg1 <> dot
    
    451
    +      _ ->
    
    452
    +        vcat [ text "Perhaps use one of"
    
    453
    +             , nest 2 $ pprWithCommas ppr_same_tc same_tc
    
    454
    +             ]
    
    455
    +  -- Otherwise, report the similarly named fields for other TyCons.
    
    456
    +  | otherwise
    
    457
    +  = vcat [ text "Perhaps use" <+> similar_field <+> text "of another type" <> colon
    
    458
    +         , nest 2 $ pprWithCommas ppr_other_tc others
    
    459
    +         ]
    
    460
    +  where
    
    461
    +    (same_tc, others) = partition ((== rep_tc) . fst) suggs
    
    462
    +    similar_field =
    
    463
    +      case others of
    
    464
    +        _:_:_ -> "one of the similarly named fields"
    
    465
    +        _     -> "the similarly named field"
    
    466
    +    ppr_same_tc (_, nm) = pprSimilarName Nothing nm
    
    467
    +    ppr_other_tc (other_tc, nm) =
    
    468
    +      quotes (ppr other_tc) <> colon <+> pprSimilarName Nothing nm
    
    469
    +
    
    440 470
     pprSigLike :: SigLike -> SDoc
    
    441 471
     pprSigLike = \case
    
    442 472
       SigLikeSig sig ->
    

  • compiler/Language/Haskell/Syntax/Expr.hs
    ... ... @@ -1403,7 +1403,7 @@ data HsMatchContext fn
    1403 1403
     
    
    1404 1404
       | ThPatSplice            -- ^A Template Haskell pattern splice
    
    1405 1405
       | ThPatQuote             -- ^A Template Haskell pattern quotation [p| (a,b) |]
    
    1406
    -  | PatSyn                 -- ^A pattern synonym declaration
    
    1406
    +  | PatSynCtx              -- ^A pattern synonym declaration
    
    1407 1407
       | LazyPatCtx             -- ^An irrefutable pattern
    
    1408 1408
     
    
    1409 1409
     {- Note [mc_fun field of FunRhs]
    
    ... ... @@ -1467,8 +1467,8 @@ qualifiedDoModuleName_maybe ctxt = case ctxt of
    1467 1467
     isPatSynCtxt :: HsMatchContext fn -> Bool
    
    1468 1468
     isPatSynCtxt ctxt =
    
    1469 1469
       case ctxt of
    
    1470
    -    PatSyn -> True
    
    1471
    -    _      -> False
    
    1470
    +    PatSynCtx -> True
    
    1471
    +    _         -> False
    
    1472 1472
     
    
    1473 1473
     isComprehensionContext :: HsStmtContext fn -> Bool
    
    1474 1474
     -- Uses comprehension syntax [ e | quals ]
    

  • testsuite/tests/overloadedrecflds/should_fail/T26480.hs
    1
    +{-# LANGUAGE DataKinds #-}
    
    2
    +{-# LANGUAGE PatternSynonyms #-}
    
    3
    +
    
    4
    +module T26480 where
    
    5
    +
    
    6
    +import Data.Proxy
    
    7
    +import GHC.TypeLits
    
    8
    +import GHC.Records
    
    9
    +
    
    10
    +import T26480_aux1 (R1)
    
    11
    +import qualified T26480_aux2 as XXX (R2)
    
    12
    +
    
    13
    +data S = MkS { fld_s :: Int }
    
    14
    +
    
    15
    +data E where
    
    16
    +  MkE :: { fld_e :: e } -> E
    
    17
    +
    
    18
    +data Q = MkQ { fld_q :: forall a. a -> a }
    
    19
    +
    
    20
    +data T = MkT { specificFieldName :: Int }
    
    21
    +
    
    22
    +data G = MkG { xyzzywyzzydyzzy :: Int }
    
    23
    +
    
    24
    +pattern P :: Int -> S
    
    25
    +pattern P { patSynField } = MkS patSynField
    
    26
    +
    
    27
    +-- Not a literal string
    
    28
    +test1 :: forall (fld_s :: Symbol). Proxy fld_s -> S -> Int
    
    29
    +test1 _ = getField @fld_s
    
    30
    +
    
    31
    +-- Not a record type
    
    32
    +test2 :: Int -> Int
    
    33
    +test2 = getField @"int_fld"
    
    34
    +
    
    35
    +-- Field out of scope: unqualified import
    
    36
    +test3a :: R1 -> Int
    
    37
    +test3a = getField @"f1"
    
    38
    +
    
    39
    +-- Field out of scope: qualified import
    
    40
    +test3b :: XXX.R2 -> Int
    
    41
    +test3b = getField @"f2"
    
    42
    +
    
    43
    +-- Existential record field
    
    44
    +test4 :: E -> Int
    
    45
    +test4 = getField @"fld_e"
    
    46
    +
    
    47
    +-- Record field contains forall
    
    48
    +test5 :: Q -> Bool -> Bool
    
    49
    +test5 = getField @"fld_q"
    
    50
    +
    
    51
    +-- Record field is misspelled
    
    52
    +test6 :: T -> Int
    
    53
    +test6 = getField @"specificFieldTame"
    
    54
    +
    
    55
    +-- Record field is for a different type
    
    56
    +test7 :: T -> Int
    
    57
    +test7 = getField @"xyzzywyzzydyzzy"
    
    58
    +
    
    59
    +-- Record field is misspelled and is for a different type
    
    60
    +test8 :: T -> Int
    
    61
    +test8 = getField @"xyzzywyzzyzyzzy"
    
    62
    +
    
    63
    +-- Pattern synonym field
    
    64
    +test9 :: S -> Int
    
    65
    +test9 = getField @"patSynField"

  • testsuite/tests/overloadedrecflds/should_fail/T26480.stderr
    1
    +T26480.hs:29:11: error: [GHC-39999]
    
    2
    +    • No instance for ‘HasField fld_s S Int’
    
    3
    +        arising from a use of ‘getField’
    
    4
    +      NB: ‘fld_s’ is a type variable, not a string literal.
    
    5
    +    • In the expression: getField @fld_s
    
    6
    +      In an equation for ‘test1’: test1 _ = getField @fld_s
    
    7
    +
    
    8
    +T26480.hs:33:9: error: [GHC-39999]
    
    9
    +    • No instance for ‘HasField "int_fld" Int Int’
    
    10
    +        arising from a use of ‘getField’
    
    11
    +      NB: ‘Int’ is not a record type.
    
    12
    +    • In the expression: getField @"int_fld"
    
    13
    +      In an equation for ‘test2’: test2 = getField @"int_fld"
    
    14
    +
    
    15
    +T26480.hs:37:10: error: [GHC-39999]
    
    16
    +    • No instance for ‘HasField "f1" R1 Int’
    
    17
    +        arising from a use of ‘getField’
    
    18
    +      NB: the record field ‘f1’ of ‘R1’ is out of scope.
    
    19
    +    • In the expression: getField @"f1"
    
    20
    +      In an equation for ‘test3a’: test3a = getField @"f1"
    
    21
    +    Suggested fix:
    
    22
    +      Add ‘f1’ to the import list in the import of ‘T26480_aux1’
    
    23
    +      (at T26480.hs:10:1-23).
    
    24
    +
    
    25
    +T26480.hs:41:10: error: [GHC-39999]
    
    26
    +    • No instance for ‘HasField "f2" XXX.R2 Int’
    
    27
    +        arising from a use of ‘getField’
    
    28
    +      NB: the record field ‘f2’ of ‘XXX.R2’ is out of scope.
    
    29
    +    • In the expression: getField @"f2"
    
    30
    +      In an equation for ‘test3b’: test3b = getField @"f2"
    
    31
    +    Suggested fix:
    
    32
    +      Add ‘f2’ to the import list in the import of ‘T26480_aux2’
    
    33
    +      (at T26480.hs:11:1-40).
    
    34
    +
    
    35
    +T26480.hs:45:9: error: [GHC-39999]
    
    36
    +    • No instance for ‘HasField "fld_e" E Int’
    
    37
    +        arising from a use of ‘getField’
    
    38
    +      NB: the record field ‘fld_e’ of ‘E’ contains existential variables.
    
    39
    +    • In the expression: getField @"fld_e"
    
    40
    +      In an equation for ‘test4’: test4 = getField @"fld_e"
    
    41
    +
    
    42
    +T26480.hs:49:9: error: [GHC-39999]
    
    43
    +    • No instance for ‘HasField "fld_q" Q (Bool -> Bool)’
    
    44
    +        arising from a use of ‘getField’
    
    45
    +      NB: the field type of the record field ‘fld_q’ of ‘Q’ is not a mono-type.
    
    46
    +    • In the expression: getField @"fld_q"
    
    47
    +      In an equation for ‘test5’: test5 = getField @"fld_q"
    
    48
    +
    
    49
    +T26480.hs:53:9: error: [GHC-39999]
    
    50
    +    • No instance for ‘HasField "specificFieldTame" T Int’
    
    51
    +        arising from a use of ‘getField’
    
    52
    +      NB: ‘T’ does not have a record field named ‘specificFieldTame’.
    
    53
    +    • In the expression: getField @"specificFieldTame"
    
    54
    +      In an equation for ‘test6’: test6 = getField @"specificFieldTame"
    
    55
    +    Suggested fix: Perhaps use ‘specificFieldName’ (line 20).
    
    56
    +
    
    57
    +T26480.hs:57:9: error: [GHC-39999]
    
    58
    +    • No instance for ‘HasField "xyzzywyzzydyzzy" T Int’
    
    59
    +        arising from a use of ‘getField’
    
    60
    +      NB: ‘T’ does not have a record field named ‘xyzzywyzzydyzzy’.
    
    61
    +      Another type has a field of this name: ‘G’.
    
    62
    +    • In the expression: getField @"xyzzywyzzydyzzy"
    
    63
    +      In an equation for ‘test7’: test7 = getField @"xyzzywyzzydyzzy"
    
    64
    +
    
    65
    +T26480.hs:61:9: error: [GHC-39999]
    
    66
    +    • No instance for ‘HasField "xyzzywyzzyzyzzy" T Int’
    
    67
    +        arising from a use of ‘getField’
    
    68
    +      NB: ‘T’ does not have a record field named ‘xyzzywyzzyzyzzy’.
    
    69
    +    • In the expression: getField @"xyzzywyzzyzyzzy"
    
    70
    +      In an equation for ‘test8’: test8 = getField @"xyzzywyzzyzyzzy"
    
    71
    +    Suggested fix:
    
    72
    +      Perhaps use the similarly named field of another type:
    
    73
    +        ‘G’: ‘xyzzywyzzydyzzy’ (line 22)
    
    74
    +
    
    75
    +T26480.hs:65:9: error: [GHC-39999]
    
    76
    +    • No instance for ‘HasField "patSynField" S Int’
    
    77
    +        arising from a use of ‘getField’
    
    78
    +      NB: ‘S’ does not have a record field named ‘patSynField’.
    
    79
    +      Pattern synonym record fields do not contribute ‘HasField’ instances.
    
    80
    +    • In the expression: getField @"patSynField"
    
    81
    +      In an equation for ‘test9’: test9 = getField @"patSynField"
    
    82
    +

  • testsuite/tests/overloadedrecflds/should_fail/T26480_aux1.hs
    1
    +module T26480_aux1 where
    
    2
    +
    
    3
    +data R1 = MkR1 { f1 :: Int }
    
    4
    +data R2 = MkR2 { f2 :: Int }

  • testsuite/tests/overloadedrecflds/should_fail/T26480_aux2.hs
    1
    +module T26480_aux2 where
    
    2
    +
    
    3
    +data R2 = MkR2 { f2 :: Int }

  • testsuite/tests/overloadedrecflds/should_fail/T26480b.hs
    1
    +{-# LANGUAGE AllowAmbiguousTypes #-}
    
    2
    +{-# LANGUAGE DataKinds #-}
    
    3
    +{-# LANGUAGE RebindableSyntax #-}
    
    4
    +{-# LANGUAGE OverloadedRecordDot #-}
    
    5
    +{-# LANGUAGE OverloadedRecordUpdate #-}
    
    6
    +
    
    7
    +module T26480b where
    
    8
    +
    
    9
    +import Prelude
    
    10
    +import Data.Proxy
    
    11
    +import GHC.TypeLits
    
    12
    +import GHC.Records
    
    13
    +
    
    14
    +
    
    15
    +setField
    
    16
    +  :: forall (fld :: Symbol) rec ty
    
    17
    +  .  HasField fld rec ty => ty -> rec -> rec
    
    18
    +setField _ r = r
    
    19
    +
    
    20
    +data N = N { no :: H }
    
    21
    +
    
    22
    +data D = MkD{ field1 :: G }
    
    23
    +
    
    24
    +data G = MkG { xyzzywyzzydyzzy :: H }
    
    25
    +
    
    26
    +data H = MkH { field2 :: Int }
    
    27
    +
    
    28
    +-- Direct usage of 'getField'
    
    29
    +test1 :: G -> H
    
    30
    +test1 = getField @"xyzzywyzzydyzza"
    
    31
    +
    
    32
    +test1' :: N -> H
    
    33
    +test1' = getField @"xyzzywyzzydyzzy"
    
    34
    +
    
    35
    +test1'' :: N -> H
    
    36
    +test1'' = getField @"ayzzywyzzydyzzy"
    
    37
    +
    
    38
    +-- Record dot, applied
    
    39
    +test2a :: G -> H
    
    40
    +test2a g = g.xyzzywyzzydyzzb
    
    41
    +
    
    42
    +test2b :: D -> H
    
    43
    +test2b g = g.field1.xyzzywyzzydyzzc
    
    44
    +
    
    45
    +-- Record dot, bare selector
    
    46
    +test3a :: G -> H
    
    47
    +test3a = (.xyzzywyzzydyzzd)
    
    48
    +
    
    49
    +test3b :: D ->H
    
    50
    +test3b = (.field1.xyzzywyzzydyzze)
    
    51
    +
    
    52
    +-- Overloaded record update
    
    53
    +test4a :: G -> G
    
    54
    +test4a d = d { xyzzywyzzydyzzf = MkG ( MkH 3 ) }
    
    55
    +
    
    56
    +test4b :: D -> D
    
    57
    +test4b d = d { field1.xyzzywyzzydyzzg = MkH 3 }

  • testsuite/tests/overloadedrecflds/should_fail/T26480b.stderr
    1
    +T26480b.hs:30:9: error: [GHC-39999]
    
    2
    +    • No instance for ‘HasField "xyzzywyzzydyzza" G H’
    
    3
    +        arising from a use of ‘getField’
    
    4
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzza’.
    
    5
    +    • In the expression: getField @"xyzzywyzzydyzza"
    
    6
    +      In an equation for ‘test1’: test1 = getField @"xyzzywyzzydyzza"
    
    7
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    8
    +
    
    9
    +T26480b.hs:33:10: error: [GHC-39999]
    
    10
    +    • No instance for ‘HasField "xyzzywyzzydyzzy" N H’
    
    11
    +        arising from a use of ‘getField’
    
    12
    +      NB: ‘N’ does not have a record field named ‘xyzzywyzzydyzzy’.
    
    13
    +      Another type has a field of this name: ‘G’.
    
    14
    +    • In the expression: getField @"xyzzywyzzydyzzy"
    
    15
    +      In an equation for ‘test1'’: test1' = getField @"xyzzywyzzydyzzy"
    
    16
    +
    
    17
    +T26480b.hs:36:11: error: [GHC-39999]
    
    18
    +    • No instance for ‘HasField "ayzzywyzzydyzzy" N H’
    
    19
    +        arising from a use of ‘getField’
    
    20
    +      NB: ‘N’ does not have a record field named ‘ayzzywyzzydyzzy’.
    
    21
    +    • In the expression: getField @"ayzzywyzzydyzzy"
    
    22
    +      In an equation for ‘test1''’: test1'' = getField @"ayzzywyzzydyzzy"
    
    23
    +    Suggested fix:
    
    24
    +      Perhaps use the similarly named field of another type:
    
    25
    +        ‘G’: ‘xyzzywyzzydyzzy’ (line 24)
    
    26
    +
    
    27
    +T26480b.hs:40:12: error: [GHC-39999]
    
    28
    +    • No instance for ‘HasField "xyzzywyzzydyzzb" G H’
    
    29
    +        arising from selecting the field ‘xyzzywyzzydyzzb’
    
    30
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzzb’.
    
    31
    +    • In the expression: g.xyzzywyzzydyzzb
    
    32
    +      In an equation for ‘test2a’: test2a g = g.xyzzywyzzydyzzb
    
    33
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    34
    +
    
    35
    +T26480b.hs:43:12: error: [GHC-39999]
    
    36
    +    • No instance for ‘HasField "xyzzywyzzydyzzc" G H’
    
    37
    +        arising from selecting the field ‘xyzzywyzzydyzzc’
    
    38
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzzc’.
    
    39
    +    • In the expression: g.field1.xyzzywyzzydyzzc
    
    40
    +      In an equation for ‘test2b’: test2b g = g.field1.xyzzywyzzydyzzc
    
    41
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    42
    +
    
    43
    +T26480b.hs:47:10: error: [GHC-39999]
    
    44
    +    • No instance for ‘HasField "xyzzywyzzydyzzd" G H’
    
    45
    +        arising from the record selector ‘xyzzywyzzydyzzd’
    
    46
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzzd’.
    
    47
    +    • In the expression: (.xyzzywyzzydyzzd)
    
    48
    +      In an equation for ‘test3a’: test3a = (.xyzzywyzzydyzzd)
    
    49
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    50
    +
    
    51
    +T26480b.hs:50:10: error: [GHC-39999]
    
    52
    +    • No instance for ‘HasField "xyzzywyzzydyzze" G H’
    
    53
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzze’.
    
    54
    +    • In the expression: (.field1.xyzzywyzzydyzze)
    
    55
    +      In an equation for ‘test3b’: test3b = (.field1.xyzzywyzzydyzze)
    
    56
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    57
    +
    
    58
    +T26480b.hs:54:12: error: [GHC-39999]
    
    59
    +    • No instance for ‘HasField "xyzzywyzzydyzzf" G G’
    
    60
    +        arising from a record update
    
    61
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzzf’.
    
    62
    +    • In the expression: d {xyzzywyzzydyzzf = MkG (MkH 3)}
    
    63
    +      In an equation for ‘test4a’:
    
    64
    +          test4a d = d {xyzzywyzzydyzzf = MkG (MkH 3)}
    
    65
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    66
    +
    
    67
    +T26480b.hs:57:12: error: [GHC-39999]
    
    68
    +    • No instance for ‘HasField "xyzzywyzzydyzzg" G H’
    
    69
    +      NB: ‘G’ does not have a record field named ‘xyzzywyzzydyzzg’.
    
    70
    +    • In the expression: d {field1.xyzzywyzzydyzzg = MkH 3}
    
    71
    +      In an equation for ‘test4b’:
    
    72
    +          test4b d = d {field1.xyzzywyzzydyzzg = MkH 3}
    
    73
    +    Suggested fix: Perhaps use ‘xyzzywyzzydyzzy’ (line 24).
    
    74
    +

  • testsuite/tests/overloadedrecflds/should_fail/all.T
    ... ... @@ -33,6 +33,8 @@ test('hasfieldfail03', normal, compile_fail, [''])
    33 33
     test('hasfieldfail04', normal, compile_fail, [''])
    
    34 34
     test('T14953', [extra_files(['T14953_A.hs', 'T14953_B.hs'])],
    
    35 35
          multimod_compile_fail, ['T14953', ''])
    
    36
    +test('T26480', extra_files(['T26480_aux1.hs', 'T26480_aux2.hs']), multimod_compile_fail, ['T26480', '-v0'])
    
    37
    +test('T26480b', normal, compile_fail, [''])
    
    36 38
     test('DuplicateExports', normal, compile_fail, [''])
    
    37 39
     test('T17420', [extra_files(['T17420A.hs'])], multimod_compile_fail,
    
    38 40
          ['T17420', ''])
    

  • testsuite/tests/overloadedrecflds/should_fail/hasfieldfail01.stderr
    1 1
     [1 of 3] Compiling HasFieldFail01_A ( HasFieldFail01_A.hs, HasFieldFail01_A.o )
    
    2 2
     [2 of 3] Compiling Main             ( hasfieldfail01.hs, hasfieldfail01.o )
    
    3
    -
    
    4 3
     hasfieldfail01.hs:9:15: error: [GHC-39999]
    
    5 4
         • No instance for ‘HasField "foo" T Int’
    
    6 5
             arising from a use of ‘getField’
    
    6
    +      NB: the record field ‘foo’ of ‘T’ is out of scope.
    
    7 7
         • In the first argument of ‘print’, namely
    
    8 8
             ‘(getField @"foo" (MkT 42) :: Int)’
    
    9 9
           In the expression: print (getField @"foo" (MkT 42) :: Int)
    
    10 10
           In an equation for ‘main’:
    
    11 11
               main = print (getField @"foo" (MkT 42) :: Int)
    
    12
    +    Suggested fix:
    
    13
    +      Add ‘foo’ to the import list in the import of ‘HasFieldFail01_A’
    
    14
    +      (at hasfieldfail01.hs:3:1-32).
    
    15
    +

  • testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.stderr
    1
    -
    
    2 1
     hasfieldfail02.hs:11:5: error: [GHC-39999]
    
    3 2
         • No instance for ‘HasField "foo" T a1’
    
    4 3
             arising from a use of ‘getField’
    
    4
    +      NB: the field type of the record field ‘foo’ of ‘T’ is not a mono-type.
    
    5 5
         • In the expression: getField @"foo" (MkT id)
    
    6 6
           In an equation for ‘x’: x = getField @"foo" (MkT id)
    
    7 7
     
    
    8 8
     hasfieldfail02.hs:17:5: error: [GHC-39999]
    
    9 9
         • No instance for ‘HasField "bar" U a0’
    
    10 10
             arising from a use of ‘getField’
    
    11
    +      NB: the record field ‘bar’ of ‘U’ contains existential variables.
    
    11 12
         • In the expression: getField @"bar" (MkU True)
    
    12 13
           In an equation for ‘y’: y = getField @"bar" (MkU True)
    
    14
    +

  • testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
    ... ... @@ -16,6 +16,7 @@ RecordDotSyntaxFail11.hs:8:3: error: [GHC-39999]
    16 16
     
    
    17 17
     RecordDotSyntaxFail11.hs:8:11: error: [GHC-39999]
    
    18 18
         • No instance for ‘GHC.Internal.Records.HasField "baz" Int a0’
    
    19
    +      NB: ‘Int’ is not a record type.
    
    19 20
         • In the second argument of ‘($)’, namely ‘(.foo.bar.baz) a’
    
    20 21
           In a stmt of a 'do' block: print $ (.foo.bar.baz) a
    
    21 22
           In the expression:
    

  • testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.hs
    ... ... @@ -28,10 +28,26 @@ data Baz = Baz { baz :: Quux } deriving (Show, Eq)
    28 28
     instance HasField "baz" Baz Quux where
    
    29 29
         hasField r = (\x -> case r of Baz { .. } -> Baz { baz = x, .. }, baz r)
    
    30 30
     
    
    31
    --- 'Quux' has a 'quux' field of type 'Int'
    
    32
    -data Quux = Quux { quux :: Int } deriving (Show, Eq)
    
    31
    +-- 'Quux' has 'quux' fields of type 'Wob'
    
    32
    +data Quux = Quux { quux1, quux2, quux3 :: Wob } deriving (Show, Eq)
    
    33 33
     -- Forget to write this type's 'HasField' instance
    
    34 34
     
    
    35
    +-- 'Wob' has a field of type 'Bool'
    
    36
    +data Wob = Wob { wob :: Bool } deriving (Show, Eq)
    
    37
    +instance HasField "wob" Wob Bool where
    
    38
    +    hasField r = (\x -> case r of Wob { .. } -> Wob { wob = x, .. }, wob r)
    
    39
    +
    
    40
    +myQuux :: Quux
    
    41
    +myQuux = Quux w w w
    
    42
    +  where w = Wob { wob = True }
    
    43
    +
    
    35 44
     main = do
    
    36
    -  let a = Foo { foo = Bar{ bar = Baz { baz = Quux { quux = 42 } } } }
    
    37
    -  print $ a.foo.bar.baz.quux
    45
    +  let
    
    46
    +    a = Foo { foo = Bar{ bar = Baz { baz = myQuux } } }
    
    47
    +  print @Quux $ a.foo.bar.baz.quux1
    
    48
    +
    
    49
    +  let b = myQuux
    
    50
    +  print @Quux $ b.quux2
    
    51
    +
    
    52
    +  let c = Foo { foo = Bar{ bar = Baz { baz = myQuux } } }
    
    53
    +  print @Bool $ a.foo.bar.baz.quux3.wob

  • testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
    1
    -RecordDotSyntaxFail8.hs:37:3: error: [GHC-39999]
    
    2
    -    • Ambiguous type variable ‘a0’ arising from a use of ‘print’
    
    3
    -      prevents the constraint ‘(Show a0)’ from being solved.
    
    4
    -      Probable fix: use a type annotation to specify what ‘a0’ should be.
    
    5
    -      Potentially matching instances:
    
    6
    -        instance Show Ordering -- Defined in ‘GHC.Internal.Show’
    
    7
    -        instance Show Bar -- Defined at RecordDotSyntaxFail8.hs:22:41
    
    8
    -        ...plus 29 others
    
    9
    -        ...plus 13 instances involving out-of-scope types
    
    10
    -        (use -fprint-potential-instances to see them all)
    
    11
    -    • In the first argument of ‘($)’, namely ‘print’
    
    12
    -      In a stmt of a 'do' block: print $ ....baz.quux
    
    1
    +RecordDotSyntaxFail8.hs:47:17: error: [GHC-39999]
    
    2
    +    • No instance for ‘HasField "quux1" Quux Quux’
    
    3
    +        arising from selecting the field ‘quux1’
    
    4
    +      NB: ‘HasField’ is not the built-in ‘GHC.Internal.Records.HasField’ class.
    
    5
    +    • In the second argument of ‘($)’, namely ‘....bar.baz.quux1’
    
    6
    +      In a stmt of a 'do' block: print @Quux $ ....baz.quux1
    
    13 7
           In the expression:
    
    14 8
             do let a = Foo {foo = ...}
    
    15
    -           print $ ....quux
    
    9
    +           print @Quux $ ....quux1
    
    10
    +           let b = myQuux
    
    11
    +           print @Quux $ b.quux2
    
    12
    +           let c = Foo {foo = ...}
    
    13
    +           ...
    
    16 14
     
    
    17
    -RecordDotSyntaxFail8.hs:37:11: error: [GHC-39999]
    
    18
    -    • No instance for ‘HasField "quux" Quux a0’
    
    19
    -        arising from selecting the field ‘quux’
    
    20
    -    • In the second argument of ‘($)’, namely ‘....bar.baz.quux’
    
    21
    -      In a stmt of a 'do' block: print $ ....baz.quux
    
    15
    +RecordDotSyntaxFail8.hs:50:17: error: [GHC-39999]
    
    16
    +    • No instance for ‘HasField "quux2" Quux Quux’
    
    17
    +        arising from selecting the field ‘quux2’
    
    18
    +      NB: ‘HasField’ is not the built-in ‘GHC.Internal.Records.HasField’ class.
    
    19
    +    • In the second argument of ‘($)’, namely ‘b.quux2’
    
    20
    +      In a stmt of a 'do' block: print @Quux $ b.quux2
    
    22 21
           In the expression:
    
    23 22
             do let a = Foo {foo = ...}
    
    24
    -           print $ ....quux
    
    25
    -    Suggested fix:
    
    26
    -      NB: There is no field selector ‘quux :: Quux
    
    27
    -                                              -> a0’ in scope for record type ‘Quux’
    
    23
    +           print @Quux $ ....quux1
    
    24
    +           let b = myQuux
    
    25
    +           print @Quux $ b.quux2
    
    26
    +           let c = Foo {foo = ...}
    
    27
    +           ...
    
    28
    +
    
    29
    +RecordDotSyntaxFail8.hs:53:17: error: [GHC-39999]
    
    30
    +    • No instance for ‘HasField "quux3" Quux r0’
    
    31
    +        arising from selecting the field ‘quux3’
    
    32
    +      NB: ‘HasField’ is not the built-in ‘GHC.Internal.Records.HasField’ class.
    
    33
    +    • In the expression: ....bar.baz.quux3
    
    34
    +      In the second argument of ‘($)’, namely ‘....baz.quux3.wob’
    
    35
    +      In a stmt of a 'do' block: print @Bool $ ....quux3.wob
    
    28 36
     

  • testsuite/tests/rename/should_fail/T19843h.stderr
    ... ... @@ -29,7 +29,7 @@ T19843h.hs:24:8: error: [GHC-39999]
    29 29
         • In the expression: undefined.getAll
    
    30 30
           In an equation for ‘quur’: quur = undefined.getAll
    
    31 31
         Suggested fixes:
    
    32
    -      • Perhaps use record field of Alt ‘getAlt’ (imported from Data.Monoid)
    
    33 32
           • Add ‘getAll’ to the import list in the import of ‘Data.Monoid’
    
    34
    -        (at T19843h.hs:9:1-28).
    
    33
    +        (at T19843h.hs:8:1-46).
    
    34
    +      • Perhaps use record field of Alt ‘getAlt’ (imported from Data.Monoid)
    
    35 35