summaryrefslogtreecommitdiff
path: root/compiler/deSugar/Match.hs
diff options
context:
space:
mode:
authorHE, Tao <sighingnow@gmail.com>2018-06-03 00:38:30 -0400
committerBen Gamari <ben@smart-cactus.org>2018-06-03 01:08:39 -0400
commit1f88f541aad1e36d01f22f9e71dfbc247e6558e2 (patch)
treee874d9ad14c67cb555d0af02e99d9dfabed990b6 /compiler/deSugar/Match.hs
parentf68c2cb60f881a0a41ae2e8cafc5de193ef9c3fb (diff)
downloadhaskell-1f88f541aad1e36d01f22f9e71dfbc247e6558e2.tar.gz
Improve exhaustiveness checking for literal values and patterns, fix #14546
Currently, we parse both the **integral literal** value and the patterns as `OverLit HsIntegral`. For example: ``` case 0::Int of 0 -> putStrLn "A" 1 -> putStrLn "B" _ -> putStrLn "C" ``` When checking the exhaustiveness of pattern matching, we translate the `0` in value position as `PmOLit`, but translate the `0` and `1` in pattern position as `PmSLit`. The inconsistency leads to the failure of `eqPmLit` to detect the equality and report warning of "Pattern match is redundant" on pattern `0`, as reported in #14546. In this patch we remove the specialization of `OverLit` patterns, and keep the overloaded number literal in pattern as it is to maintain the consistency. Now we can capture the exhaustiveness of pattern `0` and the redundancy of pattern `1` and `_`. For **string literals**, we parse the string literals as `HsString`. When `OverloadedStrings` is enabled, it further be turned as `HsOverLit HsIsString`, whether it's type is `String` or not. For example: ``` case "foo" of "foo" -> putStrLn "A" "bar" -> putStrLn "B" "baz" -> putStrLn "C" ``` Previously, the overloaded string values are translated to `PmOLit` and the non-overloaded string values are translated to `PmSLit`. However the string patterns, both overloaded and non-overloaded, are translated to list of characters. The inconsistency leads to wrong warnings about redundant and non-exhaustive pattern matching warnings, as reported in #14546. In order to catch the redundant pattern in following case: ``` case "foo" of ('f':_) -> putStrLn "A" "bar" -> putStrLn "B" ``` In this patch, we translate non-overloaded string literals, both in value position and pattern position, as list of characters. For overloaded string literals, we only translate it to list of characters only when it's type is `stringTy`, since we know nothing about the `toString` methods. But we know that if two overloaded strings are syntax equal, then they are equal. Then if it's type is not `stringTy`, we just translate it to `PmOLit`. We can still capture the exhaustiveness of pattern `"foo"` and the redundancy of pattern `"bar"` and `"baz"` in the following code: ``` {-# LANGUAGE OverloadedStrings #-} main = do case "foo" of "foo" -> putStrLn "A" "bar" -> putStrLn "B" "baz" -> putStrLn "C" ``` Test Plan: make test TEST="T14546" Reviewers: bgamari, simonpj Reviewed By: bgamari, simonpj Subscribers: simonpj, thomie, carter GHC Trac Issues: #14546 Differential Revision: https://phabricator.haskell.org/D4571
Diffstat (limited to 'compiler/deSugar/Match.hs')
-rw-r--r--compiler/deSugar/Match.hs2
1 files changed, 1 insertions, 1 deletions
diff --git a/compiler/deSugar/Match.hs b/compiler/deSugar/Match.hs
index fabbe2bc2f..ec831acdb1 100644
--- a/compiler/deSugar/Match.hs
+++ b/compiler/deSugar/Match.hs
@@ -465,7 +465,7 @@ tidy1 _ (LitPat _ lit)
-- NPats: we *might* be able to replace these w/ a simpler form
tidy1 _ (NPat ty (L _ lit) mb_neg eq)
- = return (idDsWrapper, tidyNPat tidyLitPat lit mb_neg eq ty)
+ = return (idDsWrapper, tidyNPat lit mb_neg eq ty)
-- Everything else goes through unchanged...