Proposal: give Ptr a nominal role

David Feuer david.feuer at gmail.com
Tue Oct 30 18:18:03 UTC 2018


Your simpler version won't even compile, and it gives Ptr the wrong kind.

I don't *think* anything breaks at all, unless it's using coerce on Ptr
types (the fix is easy). Note in particular that Ptr doesn't have a Generic
instance.

The extra safety is at the Storable use sites. If you have some type that
has a Ptr buried in it somewhere, coerce it to something else, and then
call a function that uses a (different) Storable instance for that field,
you're in trouble. With this change, the compiler will let you know that
there's a buried Ptr in there and (after verifying that it's okay) you can
introduce the coercibility explicitly to explain that it's fine.

On Tue, Oct 30, 2018, 2:06 PM Carter Schonwald <carter.schonwald at gmail.com>
wrote:

> hey David, heres a simpler version (attached below), that I think
> accomplishes the same goal.
>
> One issue, that would need to be evaluated empirically: how many type
> class instances would break from this change? Would any?
>
> is it Storable instances that are an issue, or things that use storable?
>
> what safety is gained vs what is impacted? (i guess i mostly just wanna
> understand what would be broken by this change, a lot of code in the wild
> uses pointers for systems integrations)
>
>
>     newtype Ptr a = Ptr  Addr#
>     type role Ptr nominal
>
>
>     castPtr :: Ptr a -> Ptr b
>     castPtr = unsafeCoerce
>
>     ptrCoercible
>       :: ((forall a b. Coercible (Ptr a) (Ptr b)) => r)
>       -> r
>     ptrCoercible r = r
>
>     ptrCoercion :: Coercion (Ptr a) (Ptr b)
>     ptrCoercion = Coercion
>
>
> On Tue, Oct 30, 2018 at 1:57 PM David Feuer <david.feuer at gmail.com> wrote:
>
>> Currently, we have
>>
>> data Ptr a = Ptr Addr#
>> type role Ptr phantom
>>
>> This is weird: accidentally coercing a pointer to a different type is
>> very bad. The only reason Ptr has this role is that without it, castPtr and
>> such may not be free or will involve unsafe coercions.
>>
>> Thankfully, we have enough power to fix this now.
>>
>>     data Addr = Ptr_ Addr#
>>
>>     newtype Ptr a = Ptr_ Addr
>>     type role Ptr nominal
>>
>>     pattern Ptr :: Addr# -> Ptr a
>>     pattern Ptr a# = Ptr_ (Addr a#)
>>
>>     castPtr :: Ptr a -> Ptr b
>>     castPtr (Ptr a) = Ptr a
>>
>>     ptrCoercible
>>       :: ((forall a b. Coercible (Ptr a) (Ptr b)) => r)
>>       -> r
>>     ptrCoercible r = r
>>
>>     ptrCoercion :: Coercion (Ptr a) (Ptr b)
>>     ptrCoercion = Coercion
>>
>> I propose that we do this.
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20181030/aa2c19ae/attachment.html>


More information about the Libraries mailing list