Skip to content

Make the pattern match exhaustiveness checker smarter about UnliftedDatatypes

Motivation

In recent versions of GHC, the pattern match exhaustiveness checker has become smarter, and code like

{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
module Main where
import Data.Kind (Type)

type Foo :: Type -> Type -> Type 
data Foo a b = 
      Bar !a
    | Baz b

type MyVoid :: Type
data MyVoid

v :: Foo MyVoid Char
v = Baz 'c'

main :: IO ()
main = case v of
    -- The Baz case is impossible
    Baz c -> putChar c

doesn't emit a "Pattern match(es) are non-exhaustive" warning.

Now that we have UnliftedDatatypes in 9.2.1, it seems to me that the exhaustiveness checker could be equally smart about code like

{-# LANGUAGE UnliftedDatatypes  #-}
{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
module Main where
import Data.Kind (Type)
import GHC.Exts (UnliftedType)

type Foo :: UnliftedType -> Type -> Type 
data Foo a b = 
      Bar a -- no need for strictness annotation
    | Baz b

type MyVoid :: UnliftedType
data MyVoid

v :: Foo MyVoid Char
v = Baz 'c'

main :: IO ()
main = case v of
    -- The Baz case is impossible
    -- MyVoid has no values, and it can't 
    -- be undefined because it's unlifted.
    Baz c -> putChar c

Proposal

Make the pattern match exhaustiveness checker more aware of impossible branches caused by the use of UnliftedDatatypes.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information