[Haskell-cafe] Generalized Newtype Deriving not allowed in Safe Haskell

David Feuer david.feuer at gmail.com
Fri Apr 10 22:54:18 UTC 2015


I think a module exporting some but not all data constructors of a type is
fundamentally broken behavior. I would generally be in favor of prohibiting
it altogether, and I would be strongly opposed to letting continued support
for it break anything else.
On Apr 10, 2015 9:05 AM, "Douglas McClean" <douglas.mcclean at gmail.com>
wrote:

> I don't think that 2+3 is equivalent to 2', because an explicit import
> list or hiding list could've brought only some of the datatype's
> constructors into visibility.
>
> On Fri, Apr 10, 2015 at 8:07 AM, Richard Eisenberg <eir at cis.upenn.edu>
> wrote:
>
>> Here's an idea: For a module to be Safe, then for each exported datatype,
>> one of the following must hold:
>> 1) The datatype comes with a role annotation.
>> 2) The module exports all of the datatype's constructors.
>> 3) If the datatype is defined in a place other than the current module,
>> the current module exports no fewer data constructors than are exported in
>> the datatype's defining module.
>>
>> Why?
>> 1) The role annotation, even if it has no effect, shows that the
>> programmer has considered roles. Any mistake here is clearly the
>> programmer's fault.
>> 2) This datatype is clearly meant not to be abstract. `Coercible` then
>> gives clients no more power than they already have.
>> 3) This is subtler. It is a common idiom to export a datatype's
>> constructors from a package-internal module, but then never to export the
>> constructors beyond the package. If such a datatype has a role annotation
>> (in its defining module, of course), then we're fine, even if it is
>> exported abstractly later. However, suppose we are abstractly re-exporting
>> a datatype that exports its constructors from its defining module. If there
>> is no role annotation on the datatype, we're in trouble and should fail.
>> BUT, if the datatype were exported abstractly in its defining module, then
>> we don't need to fail on re-export, because nothing has changed.
>>
>>
>> Actually, we could simplify the conditions. Change (2) to:
>>
>> 2') The module exports all of the datatype's visible constructors.
>>
>> I think explaining in terms of separate rules (2) and (3) is a little
>> clearer, because the re-export case is slightly subtle, and this subtlety
>> can be lost in (2').
>>
>> This proposal would require tracking (in interface files, too) whether or
>> not a datatype comes with a role annotation. This isn't hard, though. It
>> might even help in pretty-printing.
>>
>>
>> An alternative would be to have a way of setting roles differently on
>> export than internally. I don't think this breaks the type system, but it's
>> yet another thing to specify and support. And we'd have to consider the
>> possibility that some module will import a datatype from multiple
>> re-exporting modules, each with different ascribed role annotations. Is
>> this an error? Does GHC take some sort of least upper bound? I prefer not
>> to go here, but there's nothing terribly wrong with this approach.
>>
>> Richard
>>
>> On Apr 10, 2015, at 9:37 AM, David Terei <dave.terei at gmail.com> wrote:
>>
>> > I'll prepare a patch for the userguide soon.
>> >
>> > As for something better, yes I think we can and should. It's on my
>> > todo list :) Basically, the new-GND design has all the mechanisms to
>> > be safe, but sadly the defaults are rather worrying. Without explicit
>> > annotations from the user, module abstractions are broken. This is why
>> > we left GND out of Safe Haskell for the moment as it is a subtle and
>> > easy mistake to make.
>> >
>> > If the module contained explicit role annotations then it could be
>> > allowed. The discussion in
>> > https://ghc.haskell.org/trac/ghc/ticket/8827 has other solutions that
>> > I prefer, such as only exporting the Coerce instance if all the
>> > constructors are exported, it seems that the ship sailed on these
>> > bigger changes sadly.
>> >
>> > Cheers,
>> > David
>> >
>> > On 9 April 2015 at 00:56, Simon Peyton Jones <simonpj at microsoft.com>
>> wrote:
>> >> There is a long discussion on
>> https://ghc.haskell.org/trac/ghc/ticket/8827
>> >> about whether the new Coercible story makes GND ok for Safe Haskell.
>> At a
>> >> type-soundness level, definitely yes.  But there are other
>> less-clear-cut
>> >> issues like “breaking abstractions” to consider.  The decision on the
>> ticket
>> >> (comment:36) seems to be: GND stays out of Safe Haskell for now, but
>> there
>> >> is room for a better proposal.
>> >>
>> >>
>> >>
>> >> I don’t have an opinion myself. David Terei and David Mazieres are in
>> the
>> >> driving seat, but I’m sure they’ll be responsive to user input.
>> >>
>> >>
>> >>
>> >> However, I think the user manual may not have kept up with #8827.  The
>> >> sentence “GeneralizedNewtypeDeriving — It can be used to violate
>> constructor
>> >> access control, by allowing untrusted code to manipulate protected data
>> >> types in ways the data type author did not intend, breaking invariants
>> they
>> >> have established.”  vanished from the 7.8 user manual (links below).
>> Maybe
>> >> it should be restored.
>> >>
>> >>
>> >>
>> >> Safe Haskell aficionados, would you like to offer a patch for the
>> manual?
>> >> And maybe also a less drastic remedy than omitting GND altogether?
>> >>
>> >>
>> >>
>> >> Simon
>> >>
>> >>
>> >>
>> >> From: Omari Norman [mailto:omari at smileystation.com]
>> >> Sent: 09 April 2015 02:44
>> >> To: haskell Cafe
>> >> Subject: Generalized Newtype Deriving not allowed in Safe Haskell
>> >>
>> >>
>> >>
>> >> When compiling code with Generalized Newtype Deriving and the
>> -fwarn-unsafe
>> >> flag, I get
>> >>
>> >>
>> >>
>> >> -XGeneralizedNewtypeDeriving is not allowed in Safe Haskell
>> >>
>> >>
>> >>
>> >> This happens both in GHC 7.8 and GHC 7.10.
>> >>
>> >>
>> >>
>> >> I thought I remembered reading somewhere that GNTD is now part of the
>> safe
>> >> language?  The GHC manual used to state that GNTD is not allowed in
>> Safe
>> >> Haskell:
>> >>
>> >>
>> >>
>> >>
>> https://downloads.haskell.org/~ghc/7.6.3/docs/html/users_guide/safe-haskell.html#safe-language
>> >>
>> >>
>> >>
>> >> But this language on GNTD not being part of the safe language was
>> removed in
>> >> the 7.8 manual:
>> >>
>> >>
>> >>
>> >>
>> https://downloads.haskell.org/~ghc/7.8.2/docs/html/users_guide/safe-haskell.html#safe-language
>> >>
>> >>
>> >>
>> >> The GHC release notes don't say anything about this one way or the
>> other.
>> >> Thoughts?
>> >>
>> >>
>> >> _______________________________________________
>> >> ghc-devs mailing list
>> >> ghc-devs at haskell.org
>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>> >>
>> > _______________________________________________
>> > ghc-devs mailing list
>> > ghc-devs at haskell.org
>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>> >
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>>
>
>
>
> --
> J. Douglas McClean
>
> (781) 561-5540 (cell)
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150410/2f9072fa/attachment-0001.html>


More information about the Haskell-Cafe mailing list