[GHC] #15398: GADT deriving Ord generates inaccessible code in a pattern with constructor.
GHC
ghc-devs at haskell.org
Mon Jul 16 15:11:13 UTC 2018
#15398: GADT deriving Ord generates inaccessible code in a pattern with
constructor.
--------------------------------------+---------------------------------
Reporter: philderbeast | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.2.2
Keywords: | Operating System: MacOS X
Architecture: x86_64 (amd64) | Type of failure: None/Unknown
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
--------------------------------------+---------------------------------
I added a second type parameter `k` to a GADT `Zone` and found that when
deriving Ord with standalone deriving, the generated code has errors in
ghc-8.2.2. There's a reproduction repo for this;
https://github.com/BlockScope/zone-inaccessible-code-deriving-ord.
I found I needed at least three constructors in `Zone` to get this error.
#8128 seemed relevant for being about standalone deriving of a GADT. That
being fixed, I tried with ghc-head that I built from source. With this
version I found that the same code faults exist in the generated code but
are treated as warnings by ghc-8.7.2
{{{
> inplace/bin/ghc-stage2 --version
The Glorious Glasgow Haskell Compilation System, version 8.7.20180715
}}}
{{{#!hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
module Flight.Zone where
newtype Radius a = Radius a deriving (Eq, Ord)
data CourseLine
data OpenDistance
data EndOfSpeedSection
-- TODO: Remove standalone deriving Eq & Ord for empty data after GHC
8.4.1
-- SEE: https://ghc.haskell.org/trac/ghc/ticket/7401
deriving instance Eq CourseLine
deriving instance Eq OpenDistance
deriving instance Eq EndOfSpeedSection
deriving instance Ord CourseLine
deriving instance Ord OpenDistance
deriving instance Ord EndOfSpeedSection
data Zone k a where
Point :: (Eq a, Ord a) => Zone CourseLine a
Vector :: (Eq a, Ord a) => Zone OpenDistance a
Conical :: (Eq a, Ord a) => Radius a -> Zone EndOfSpeedSection a
deriving instance Eq a => Eq (Zone k a)
deriving instance (Eq a, Ord a) => Ord (Zone k a)
}}}
The error;
{{{
/.../Zone.hs:25:1: error:
• Couldn't match type ‘OpenDistance’ with ‘CourseLine’
Inaccessible code in
a pattern with constructor:
Point :: forall a. (Eq a, Ord a) => Zone CourseLine a,
in a case alternative
• In the pattern: Point {}
In a case alternative: Point {} -> GT
In the expression:
case b of
Point {} -> GT
Vector -> EQ
_ -> LT
When typechecking the code for ‘compare’
in a derived instance for ‘Ord (Zone k a)’:
To see the code I am typechecking, use -ddump-deriv
|
25 | deriving instance (Eq a, Ord a) => Ord (Zone k a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/.../Zone.hs:25:1: error:
• Couldn't match type ‘OpenDistance’ with ‘CourseLine’
Inaccessible code in
a pattern with constructor:
Point :: forall a. (Eq a, Ord a) => Zone CourseLine a,
in a case alternative
• In the pattern: Point {}
In a case alternative: Point {} -> False
In the expression:
case b of
Point {} -> False
Vector -> False
_ -> True
When typechecking the code for ‘<’
in a derived instance for ‘Ord (Zone k a)’:
To see the code I am typechecking, use -ddump-deriv
|
25 | deriving instance (Eq a, Ord a) => Ord (Zone k a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}}}
The generated code with these replacements;
{{{
:%s/GHC\.Classes\.//
:%s/GHC\.Types\.//
:%s/Flight\.Zone\.//
}}}
{{{#!hs
instance (Eq a, Ord a) =>
Ord (Zone k a) where
compare a_a2hw b_a2hx
= case a_a2hw of
Point
-> case b_a2hx of
Point -> EQ
_ -> LT
Vector
-> case b_a2hx of
Point {} -> GT
Vector -> EQ
_ -> LT
Conical a1_a2hy
-> case b_a2hx of
Conical b1_a2hz
-> (a1_a2hy `compare` b1_a2hz)
_ -> GT
(<) a_a2hA b_a2hB
= case a_a2hA of
Point
-> case b_a2hB of
Point -> False
_ -> True
Vector
-> case b_a2hB of
Point {} -> False
Vector -> False
_ -> True
Conical a1_a2hC
-> case b_a2hB of
Conical b1_a2hD -> (a1_a2hC < b1_a2hD)
_ -> False
(<=) a_a2hE b_a2hF
= not ((<) b_a2hF a_a2hE)
(>) a_a2hG b_a2hH = (<) b_a2hH a_a2hG
(>=) a_a2hI b_a2hJ
= not ((<) a_a2hI b_a2hJ)
instance Eq a =>
Eq (Zone k a) where
(==) (Point) (Point)
= True
(==) (Vector) (Vector)
= True
(==)
(Conical a1_a2hK)
(Conical b1_a2hL)
= ((a1_a2hK == b1_a2hL))
(==) _ _ = False
(/=) a_a2hM b_a2hN
= not ((==) a_a2hM b_a2hN)
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15398>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list