[GHC] #15385: -Wincomplete-patterns gets confused when combining GADTs and pattern guards
GHC
ghc-devs at haskell.org
Sun Jul 15 15:01:19 UTC 2018
#15385: -Wincomplete-patterns gets confused when combining GADTs and pattern guards
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.5
Keywords: | Operating System: Unknown/Multiple
PatternMatchWarnings |
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
Consider the following code:
{{{#!hs
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wincomplete-patterns #-}
module Bug where
import Data.Kind
data family Sing :: forall k. k -> Type
newtype Id a = MkId a
data So :: Bool -> Type where
Oh :: So True
data instance Sing :: Bool -> Type where
SFalse :: Sing False
STrue :: Sing True
data instance Sing :: Ordering -> Type where
SLT :: Sing LT
SEQ :: Sing EQ
SGT :: Sing GT
data instance Sing :: forall a. Id a -> Type where
SMkId :: Sing x -> Sing (MkId x)
class POrd a where
type (x :: a) `Compare` (y :: a) :: Ordering
class SOrd a where
sCompare :: forall (x :: a) (y :: a).
Sing x -> Sing y -> Sing (x `Compare` y)
type family (x :: a) <= (y :: a) :: Bool where
x <= y = LeqCase (x `Compare` y)
type family LeqCase (o :: Ordering) :: Bool where
LeqCase LT = True
LeqCase EQ = True
LeqCase GT = False
(%<=) :: forall a (x :: a) (y :: a). SOrd a
=> Sing x -> Sing y -> Sing (x <= y)
sx %<= sy =
case sx `sCompare` sy of
SLT -> STrue
SEQ -> STrue
SGT -> SFalse
class (POrd a, SOrd a) => VOrd a where
leqReflexive :: forall (x :: a). Sing x -> So (x <= x)
instance POrd a => POrd (Id a) where
type MkId x `Compare` MkId y = x `Compare` y
instance SOrd a => SOrd (Id a) where
SMkId sx `sCompare` SMkId sy = sx `sCompare` sy
-----
instance VOrd a => VOrd (Id a) where
leqReflexive (SMkId sa)
| Oh <- leqReflexive sa
= case sa `sCompare` sa of
SLT -> Oh
SEQ -> Oh
-- SGT -> undefined
}}}
What exactly this code does isn't terribly important. The important bit is
that last instance (`VOrd (Id a)`). That //should// be total, but GHC
disagrees:
{{{
GHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:63:7: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In a case alternative: Patterns not matched: SGT
|
63 | = case sa `sCompare` sa of
| ^^^^^^^^^^^^^^^^^^^^^^^^...
}}}
As evidence that this warning is bogus, if you uncomment the last line,
then GHC correctly observes that that line is inaccessible:
{{{
GHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:66:9: warning: [-Winaccessible-code]
• Couldn't match type ‘'True’ with ‘'False’
Inaccessible code in
a pattern with constructor: SGT :: Sing 'GT, in a case alternative
• In the pattern: SGT
In a case alternative: SGT -> undefined
In the expression:
case sa `sCompare` sa of
SLT -> Oh
SEQ -> Oh
SGT -> undefined
|
66 | SGT -> undefined
| ^^^
}}}
Clearly, something is afoot in the coverage checker.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15385>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list