diff options
author | Adam Gundry <adam@well-typed.com> | 2021-01-08 19:27:45 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-02-26 16:25:39 -0500 |
commit | 80eda911ef1ea711a9e3e51ad510dfe5a9a09ae9 (patch) | |
tree | aa7e1614c76b5c5c31ca772c8300a115c62e9684 /compiler/GHC | |
parent | 29e7f318209794206033065cdc0874a5afe0ad47 (diff) | |
download | haskell-80eda911ef1ea711a9e3e51ad510dfe5a9a09ae9.tar.gz |
Implement -Wambiguous-fields
Fixes #18966. Adds a new warning -Wambiguous-fields for uses of field selectors
or record updates that will be rejected in the future, when the DuplicateRecordFields
extension is simplified per https://github.com/ghc-proposals/ghc-proposals/pull/366.
Diffstat (limited to 'compiler/GHC')
-rw-r--r-- | compiler/GHC/Driver/Flags.hs | 1 | ||||
-rw-r--r-- | compiler/GHC/Driver/Session.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Tc/Gen/Expr.hs | 19 | ||||
-rw-r--r-- | compiler/GHC/Tc/Gen/Head.hs | 31 |
4 files changed, 49 insertions, 4 deletions
diff --git a/compiler/GHC/Driver/Flags.hs b/compiler/GHC/Driver/Flags.hs index 3d0908caa0..7867d4bd04 100644 --- a/compiler/GHC/Driver/Flags.hs +++ b/compiler/GHC/Driver/Flags.hs @@ -505,6 +505,7 @@ data WarningFlag = | Opt_WarnInvalidHaddock -- Since 8.12 | Opt_WarnOperatorWhitespaceExtConflict -- Since 9.2 | Opt_WarnOperatorWhitespace -- Since 9.2 + | Opt_WarnAmbiguousFields -- Since 9.2 deriving (Eq, Show, Enum) -- | Used when outputting warnings: if a reason is given, it is diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index 7afcf7309c..a0a6153b0b 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -3055,6 +3055,7 @@ wWarningFlagsDeps = [ -- Please keep the list of flags below sorted alphabetically flagSpec "alternative-layout-rule-transitional" Opt_WarnAlternativeLayoutRuleTransitional, + flagSpec "ambiguous-fields" Opt_WarnAmbiguousFields, depFlagSpec "auto-orphans" Opt_WarnAutoOrphans "it has no effect", flagSpec "cpp-undef" Opt_WarnCPPUndef, @@ -3909,6 +3910,7 @@ standardWarnings -- see Note [Documenting warning flags] Opt_WarnDerivingDefaults, Opt_WarnOverflowedLiterals, Opt_WarnEmptyEnumerations, + Opt_WarnAmbiguousFields, Opt_WarnMissingFields, Opt_WarnMissingMethods, Opt_WarnWrongDoBind, diff --git a/compiler/GHC/Tc/Gen/Expr.hs b/compiler/GHC/Tc/Gen/Expr.hs index 8ad1e59796..dfb9d6abd9 100644 --- a/compiler/GHC/Tc/Gen/Expr.hs +++ b/compiler/GHC/Tc/Gen/Expr.hs @@ -1216,13 +1216,16 @@ disambiguateRecordBinds record_expr record_rho rbnds res_ty -- Multiple possible parents: try harder to disambiguate -- Can we get a parent TyCon from the pushed-in type? - _:_ | Just p <- tyConOfET fam_inst_envs res_ty -> return (RecSelData p) + _:_ | Just p <- tyConOfET fam_inst_envs res_ty -> + do { reportAmbiguousField p + ; return (RecSelData p) } -- Does the expression being updated have a type signature? -- If so, try to extract a parent TyCon from it | Just {} <- obviousSig (unLoc record_expr) , Just tc <- tyConOf fam_inst_envs record_rho - -> return (RecSelData tc) + -> do { reportAmbiguousField tc + ; return (RecSelData tc) } -- Nothing else we can try... _ -> failWithTc badOverloadedUpdate @@ -1263,6 +1266,18 @@ disambiguateRecordBinds record_expr record_rho rbnds res_ty ; return $ L l upd { hsRecFieldLbl = L loc (Unambiguous i (L loc lbl)) } } + -- See Note [Deprecating ambiguous fields] in GHC.Tc.Gen.Head + reportAmbiguousField :: TyCon -> TcM () + reportAmbiguousField parent_type = + setSrcSpan loc $ warnIfFlag Opt_WarnAmbiguousFields True $ + vcat [ text "The record update" <+> ppr rupd + <+> text "with type" <+> ppr parent_type + <+> text "is ambiguous." + , text "This will not be supported by -XDuplicateRecordFields in future releases of GHC." + ] + where + rupd = RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds, rupd_ext = noExtField } + loc = getLoc (head rbnds) {- Game plan for record bindings diff --git a/compiler/GHC/Tc/Gen/Head.hs b/compiler/GHC/Tc/Gen/Head.hs index 7dc993d8cc..faf5e0f2f2 100644 --- a/compiler/GHC/Tc/Gen/Head.hs +++ b/compiler/GHC/Tc/Gen/Head.hs @@ -435,8 +435,25 @@ add_head_ctxt fun args thing_inside * * ********************************************************************* -} -{- Note [Disambiguating record fields] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- +Note [Deprecating ambiguous fields] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In the future, the -XDuplicateRecordFields extension will no longer support +disambiguating record fields during type-checking (as described in Note +[Disambiguating record fields]). For now, the -Wambiguous-fields option will +emit a warning whenever an ambiguous field is resolved using type information. +In a subsequent GHC release, this functionality will be removed and the warning +will turn into an ambiguity error in the renamer. + +For background information, see GHC proposal #366 +(https://github.com/ghc-proposals/ghc-proposals/pull/366). + + +Note [Disambiguating record fields] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +NB. The following is going to be removed: see +Note [Deprecating ambiguous fields]. + When the -XDuplicateRecordFields extension is used, and the renamer encounters a record selector or update that it cannot immediately disambiguate (because it involves fields that belong to multiple @@ -601,6 +618,16 @@ finish_ambiguous_selector lr@(L _ rdr) parent_type -- See Note [Unused name reporting and HasField] in GHC.Tc.Instance.Class do { addUsedGRE True gre ; keepAlive (greMangledName gre) + -- See Note [Deprecating ambiguous fields] + ; warnIfFlag Opt_WarnAmbiguousFields True $ + vcat [ text "The field" <+> quotes (ppr rdr) + <+> text "belonging to type" <+> ppr parent_type + <+> text "is ambiguous." + , text "This will not be supported by -XDuplicateRecordFields in future releases of GHC." + , if isLocalGRE gre + then text "You can use explicit case analysis to resolve the ambiguity." + else text "You can use a qualified import or explicit case analysis to resolve the ambiguity." + ] ; return (greMangledName gre) } } } } } -- This field name really is ambiguous, so add a suitable "ambiguous |