[GHC] #8827: Inferring Safe mode with GeneralizedNewtypeDeriving is wrong
GHC
ghc-devs at haskell.org
Fri Aug 14 17:11:16 UTC 2015
#8827: Inferring Safe mode with GeneralizedNewtypeDeriving is wrong
-------------------------------------+-------------------------------------
Reporter: goldfire | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 7.12.1
Component: Compiler | Version: 7.9
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: #8226, #8745 | Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by oerjan):
Replying to [comment:40 goldfire]:
> For this to work out, the last check above must be recursive, looking at
all datatypes mentioned in those in-scope data constructors, out to the
leaves. Otherwise, a programmer could write a trivial wrapper around a
type; all the data constructors would be in scope for the wrapper, and
then the programmer could `coerce` away. It's the recursiveness of this
check that's annoying.
Oops. What's worse, this interacts with role annotations:
{{{
module A (A) where
-- inferred type role A representable
data A a = A' a
...
{-# LANGUAGE Safe #-}
module B where
import A
type role B representative
newtype B b = B (A b)
}}}
By my literal proposal above, module `B` has just managed to achieve such
a wrapper, just with a role annotation and ''without'' `A'` in scope.
Which means my point 5 is unsupportable as given, and the closest option I
can think of requires tracking `Coercible` separately from roles - `B`
here should have the role given, since that's the inferred one, but it
should ''not'' therefore automatically be `Coercible` to `A`, except where
`A'` is in scope.
Or wait, hm. Perhaps a simpler option might be to distinguish
`representable` from `inferredRepresentable` (better name hereby
solicited), and have the rule that `inferredRepresentable` can be treated
as `representable` only when all necessary constructors are in scope,
recursively until you reach a non-`inferred` role. (Similarly for
`phantom`, I guess.) That makes the role annotation for `B` wrong because
`A`'s role is `inferredRepresentable`, and `A'` is not in scope.
Also, there should then probably be a pragma to automatically remove the
"inferred" when possible for types declared in a module.
Warning: the above was written in a bit of a hurry.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8827#comment:41>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list