Minimality of missing pattern set depends on constructor declaration order
{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-}
{-# LANGUAGE PatternSynonyms #-}
module Lib where
data B = T | F
pattern P :: B
pattern P = T
{-# COMPLETE P, F #-}
f :: B -> ()
f P = ()
pattern Q :: B
pattern Q = T
{-# COMPLETE T, Q #-}
g :: B -> ()
g Q = ()
This will generate the following warning on GHC 8.8.1:
[1 of 1] Compiling Lib ( test.hs, test.o )
test.hs:11:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘f’: Patterns not matched: F
|
11 | f P = ()
| ^^^^^^^^
test.hs:18:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘g’: Patterns not matched: T
|
18 | g Q = ()
| ^^^^^^^^
But with 8.10, this will generate the following instead:
[1 of 1] Compiling Lib ( test.hs, test.o )
test.hs:11:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘f’:
Patterns not matched:
T
F
|
11 | f P = ()
| ^^^^^^^^
test.hs:18:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘g’: Patterns not matched: T
|
18 | g Q = ()
| ^^^^^^^^
The suggestion to match on T
in f
is redundant only after we matched on F
, which fulfills the user-defined COMPLETE
set. So it's not wrong per se, but considering that g
only reports T
it seems unfortunate. This is only because T
is declared before F
, so we leak out an implementation detail.
I don't know a clever way around this that is optimal (always picks the minimum amount of patterns) and wouldn't result in combinatorial explosion in degenerate cases.
We should at least consider (hopefully not) fixing this in 8.10.