summaryrefslogtreecommitdiff
path: root/compiler/deSugar/DsBinds.hs
diff options
context:
space:
mode:
authorDavid Feuer <david.feuer@gmail.com>2017-03-02 15:01:26 -0500
committerDavid Feuer <David.Feuer@gmail.com>2017-03-02 15:01:28 -0500
commitbc332b3159613190a4dc33a067c1ab31039a8434 (patch)
treed8c61a195aba870b4083441dae4f57730b7b09af /compiler/deSugar/DsBinds.hs
parentae67619853d029ea8049a114f44e59f4ca10b990 (diff)
downloadhaskell-bc332b3159613190a4dc33a067c1ab31039a8434.tar.gz
Prohibit RULES changing constructors
Previously, `RULES` like ``` {-# RULES "JustNothing" forall x . Just x = Nothing #-} ``` were allowed. Simon Peyton Jones say this seems to have been a mistake, that such rules have never been supported intentionally, and that he doesn't know if they can break in horrible ways. Furthermore, Ben Gamari and Reid Barton are considering trying to detect the presence of "static data" that the simplifier doesn't need to traverse at all. Such rules do not play well with that. So for now, we ban them altogether. In most cases, it's possible to work around the ban using hand-written wrapper functions. Reviewers: austin, simonpj, bgamari Reviewed By: simonpj, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D3169
Diffstat (limited to 'compiler/deSugar/DsBinds.hs')
-rw-r--r--compiler/deSugar/DsBinds.hs27
1 files changed, 25 insertions, 2 deletions
diff --git a/compiler/deSugar/DsBinds.hs b/compiler/deSugar/DsBinds.hs
index 0b115cb902..0d96692a5d 100644
--- a/compiler/deSugar/DsBinds.hs
+++ b/compiler/deSugar/DsBinds.hs
@@ -837,13 +837,15 @@ decomposeRuleLhs :: [Var] -> CoreExpr -> Either SDoc ([Var], Id, [CoreExpr])
-- The 'bndrs' are the quantified binders of the rules, but decomposeRuleLhs
-- may add some extra dictionary binders (see Note [Free dictionaries])
--
--- Returns Nothing if the LHS isn't of the expected shape
+-- Returns an error message if the LHS isn't of the expected shape
-- Note [Decomposing the left-hand side of a RULE]
decomposeRuleLhs orig_bndrs orig_lhs
| not (null unbound) -- Check for things unbound on LHS
-- See Note [Unused spec binders]
= Left (vcat (map dead_msg unbound))
-
+ | Var funId <- fun2
+ , Just con <- isDataConId_maybe funId
+ = Left (constructor_msg con) -- See Note [No RULES on datacons]
| Just (fn_id, args) <- decompose fun2 args2
, let extra_bndrs = mk_extra_bndrs fn_id args
= -- pprTrace "decmposeRuleLhs" (vcat [ text "orig_bndrs:" <+> ppr orig_bndrs
@@ -899,6 +901,11 @@ decomposeRuleLhs orig_bndrs orig_lhs
| Just pred <- evVarPred_maybe bndr = text "constraint" <+> quotes (ppr pred)
| otherwise = text "variable" <+> quotes (ppr bndr)
+ constructor_msg con = vcat
+ [ text "A constructor," <+> ppr con <>
+ text ", appears as outermost match in RULE lhs."
+ , text "This rule will be ignored." ]
+
drop_dicts :: CoreExpr -> CoreExpr
drop_dicts e
= wrap_lets needed bnds body
@@ -1087,6 +1094,22 @@ the constraint is unused. We could bind 'd' to (error "unused")
but it seems better to reject the program because it's almost certainly
a mistake. That's what the isDeadBinder call detects.
+Note [No RULES on datacons]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Previously, `RULES` like
+
+ "JustNothing" forall x . Just x = Nothing
+
+were allowed. Simon Peyton Jones says this seems to have been a
+mistake, that such rules have never been supported intentionally,
+and that he doesn't know if they can break in horrible ways.
+Furthermore, Ben Gamari and Reid Barton are considering trying to
+detect the presence of "static data" that the simplifier doesn't
+need to traverse at all. Such rules do not play well with that.
+So for now, we ban them altogether as requested by #13290. See also #7398.
+
+
************************************************************************
* *
Desugaring evidence