Pattern match checking for unlifted types
I wanted to wait for the implementation of the unlifted data types proposal to actually have more of a reason to implement precise support for unlifted types in the pattern match checker. But I think implementing !3289 (closed) in the pattern match checker might be enough of a motivation to do so sooner rather than later. So here it goes (Edit: Note that g
is not really a valid testcase, as Void#
is an alias for the unboxed unit tuple and has a single inhabitant):
{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module T18249 where
import GHC.Exts
f :: Int# -> Int
-- redundant, not just inaccessible!
f !x | False = 1
f x = 2
g :: Void# -> Int
-- redundant in a weird way
-- there's no way to actually write this function
g _ = 1
h :: (# (), () #) -> Int
-- redundant, not just inaccessible!
h (# _, _ #) | False = 1
h _ = 2
i :: Int -> Int
i !_ | False = 1
i (I# !_) | False = 2
i _ = 3
Current output:
T18249.hs:10:8: warning: [-Woverlapping-patterns]
Pattern match has inaccessible right hand side
In an equation for ‘f’: f !x | False = ...
|
10 | f !x | False = 1 -- redundant, not just inaccessible!
| ^^^^^
T18249.hs:19:16: warning: [-Woverlapping-patterns]
Pattern match has inaccessible right hand side
In an equation for ‘h’: h (# _, _ #) | False = ...
|
19 | h (# _, _ #) | False = 1 -- redundant, not just inaccessible!
| ^^^^^
T18249.hs:23:13: warning: [-Woverlapping-patterns]
Pattern match has inaccessible right hand side
In an equation for ‘i’: i !_ | False = ...
|
23 | i !_ | False = 1
| ^^^^^
T18249.hs:24:13: warning: [-Woverlapping-patterns]
Pattern match has inaccessible right hand side
In an equation for ‘i’: i (I# !_) | False = ...
|
24 | i (I# !_) | False = 2 -- redundant, not just inaccessible!
| ^^^^^
The inaccessibility warnings on f
and h
should be redundancy warnings. I'm not sure how to flag g
's single clause: It's actually redundant, but if you delete it, you get a semantic error. We'd need syntax like g :: ...; g impossible.
. So better flag it as inaccessible, I think. The second branch of i
is redundant, not just inaccessible.