summaryrefslogtreecommitdiff
path: root/compiler/GHC
diff options
context:
space:
mode:
authorAdam Gundry <adam@well-typed.com>2021-01-08 19:27:45 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-02-26 16:25:39 -0500
commit80eda911ef1ea711a9e3e51ad510dfe5a9a09ae9 (patch)
treeaa7e1614c76b5c5c31ca772c8300a115c62e9684 /compiler/GHC
parent29e7f318209794206033065cdc0874a5afe0ad47 (diff)
downloadhaskell-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.hs1
-rw-r--r--compiler/GHC/Driver/Session.hs2
-rw-r--r--compiler/GHC/Tc/Gen/Expr.hs19
-rw-r--r--compiler/GHC/Tc/Gen/Head.hs31
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