summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authornineonine <mail4chemik@gmail.com>2020-05-22 00:41:55 -0700
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-08-19 18:47:39 -0400
commit731c8d3bc5a84515793e5dadb26adf52f9280e13 (patch)
tree2a5fbdc0e4eccc3b8e31fe07832755cb6ab18a70 /docs
parent0c5ed5c7eb30bc5462b67ff097c3388597265a4b (diff)
downloadhaskell-731c8d3bc5a84515793e5dadb26adf52f9280e13.tar.gz
Implement -Wredundant-bang-patterns (#17340)
Add new flag '-Wredundant-bang-patterns' that enables checks for "dead" bangs. Dead bangs are the ones that under no circumstances can force a thunk that wasn't already forced. Dead bangs are a form of redundant bangs. The new check is performed in Pattern-Match Coverage Checker along with other checks (namely, redundant and inaccessible RHSs). Given f :: Bool -> Int f True = 1 f !x = 2 we can detect dead bang patterns by checking whether @x ~ ⊥@ is satisfiable where the PmBang appears in 'checkGrdTree'. If not, then clearly the bang is dead. Such a dead bang is then indicated in the annotated pattern-match tree by a 'RedundantSrcBang' wrapping. In 'redundantAndInaccessibles', we collect all dead bangs to warn about. Note that we don't want to warn for a dead bang that appears on a redundant clause. That is because in that case, we recommend to delete the clause wholly, including its leading pattern match. Dead bang patterns are redundant. But there are bang patterns which are redundant that aren't dead, for example f !() = 0 the bang still forces the match variable, before we attempt to match on (). But it is redundant with the forcing done by the () match. We currently don't detect redundant bangs that aren't dead.
Diffstat (limited to 'docs')
-rw-r--r--docs/users_guide/9.2.1-notes.rst18
-rw-r--r--docs/users_guide/using-warnings.rst41
2 files changed, 59 insertions, 0 deletions
diff --git a/docs/users_guide/9.2.1-notes.rst b/docs/users_guide/9.2.1-notes.rst
new file mode 100644
index 0000000000..bdc0271e6f
--- /dev/null
+++ b/docs/users_guide/9.2.1-notes.rst
@@ -0,0 +1,18 @@
+.. _release-9-2-1:
+
+Version 9.2.1
+==============
+
+Compiler
+~~~~~~~~
+
+- New '-Wredundant-bang-patterns' flag that enables checks for "dead" bangs.
+ For instance, given this program: ::
+
+ f :: Bool -> Bool
+ f True = False
+ f !x = x
+
+ GHC would report that the bang on ``x`` is redundant and can be removed
+ since the argument was already forced in the first equation. For more
+ details see :ghc-flag:`-Wredundant-bang-patterns`
diff --git a/docs/users_guide/using-warnings.rst b/docs/users_guide/using-warnings.rst
index afc3b18321..353c1a07ca 100644
--- a/docs/users_guide/using-warnings.rst
+++ b/docs/users_guide/using-warnings.rst
@@ -1627,6 +1627,47 @@ of ``-W(no-)*``.
would report that the ``P{..}`` match is unused.
+.. ghc-flag:: -Wredundant-bang-patterns
+ :shortdesc: Warn about redundant bang patterns.
+ :type: dynamic
+ :reverse: -Wno-redundant-bang-patterns
+ :category:
+
+ :since: 9.2.1
+
+ .. index::
+ single: redundant, warning, bang patterns
+
+ Report dead bang patterns, where dead bangs are bang patterns that under no
+ circumstances can force a thunk that wasn't already forced. Dead bangs are a
+ form of redundant bangs. The new check is performed in pattern-match coverage
+ checker along with other checks (namely, redundant and inaccessible RHSs).
+ Given ::
+
+
+ f :: Bool -> Int
+ f True = 1
+ f !x = 2
+
+ The bang pattern on ``!x`` is dead. By the time the ``x`` in the second equation
+ is reached, ``x`` will already have been forced due to the first equation
+ (``f True = 1``). Moreover, there is no way to reach the second equation without
+ going through the first one.
+
+ Note that ``-Wredundant-bang-patterns`` will not warn about dead bangs that appear
+ on a redundant clause. That is because in that case, it is recommended to delete
+ the clause wholly, including its leading pattern match.
+
+ Dead bang patterns are redundant. But there are bang patterns which are
+ redundant that aren't dead, for example: ::
+
+
+ f !() = 0
+
+ the bang still forces the argument, before we attempt to match on ``()``. But it is
+ redundant with the forcing done by the ``()`` match. Currently such redundant bangs
+ are not considered dead, and ``-Wredundant-bang-patterns`` will not warn about them.
+
.. ghc-flag:: -Wredundant-record-wildcards
:shortdesc: Warn about record wildcard matches when the wildcard binds no patterns.
:type: dynamic