<div dir="auto"><div>Your simpler version won't even compile, and it gives Ptr the wrong kind.</div><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><div dir="auto">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.<br><br><div class="gmail_quote" dir="auto"><div dir="ltr">On Tue, Oct 30, 2018, 2:06 PM Carter Schonwald <<a href="mailto:carter.schonwald@gmail.com">carter.schonwald@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>hey David, heres a simpler version (attached below), that I think accomplishes the same goal. </div><div><br></div><div>One issue, that would need to be evaluated empirically: how many type class instances would break from this change? Would any?</div><div><br></div><div>is it Storable instances that are an issue, or things that use storable?</div><div><br></div><div>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)</div><div dir="auto"> </div><div dir="auto"><br></div><div dir="auto">    newtype Ptr a = Ptr  Addr#</div><div dir="auto">    type role Ptr nominal</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><span style="font-family:sans-serif">    castPtr :: Ptr a -> Ptr b</span><br></div><div dir="auto"><span style="font-family:sans-serif">    castPtr = unsafeCoerce</span></div><div dir="auto"><br></div><div dir="auto">    ptrCoercible</div><div dir="auto">      :: ((forall a b. Coercible (Ptr a) (Ptr b)) => r)</div><div dir="auto">      -> r</div><div dir="auto">    ptrCoercible r = r</div><div dir="auto"><br></div><div dir="auto">    ptrCoercion :: Coercion (Ptr a) (Ptr b)</div><div dir="auto">    ptrCoercion = Coercion</div><br class="m_-8242094550131160590gmail-Apple-interchange-newline"></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Oct 30, 2018 at 1:57 PM David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank" rel="noreferrer">david.feuer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Currently, we have<div dir="auto"><br></div><div dir="auto">data Ptr a = Ptr Addr#</div><div dir="auto">type role Ptr phantom</div><div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><div dir="auto">Thankfully, we have enough power to fix this now.</div><div dir="auto"><br></div><div dir="auto">    data Addr = Ptr_ Addr#</div><div dir="auto"><br></div><div dir="auto">    newtype Ptr a = Ptr_ Addr</div><div dir="auto">    type role Ptr nominal</div><div dir="auto"><br></div><div dir="auto">    pattern Ptr :: Addr# -> Ptr a</div><div dir="auto">    pattern Ptr a# = Ptr_ (Addr a#)</div><div dir="auto"><br></div><div dir="auto"><span style="font-family:sans-serif">    castPtr :: Ptr a -> Ptr b</span><br></div><div dir="auto"><span style="font-family:sans-serif">    castPtr (Ptr a) = Ptr a</span></div><div dir="auto"><br></div><div dir="auto">    ptrCoercible</div><div dir="auto">      :: ((forall a b. Coercible (Ptr a) (Ptr b)) => r)</div><div dir="auto">      -> r</div><div dir="auto">    ptrCoercible r = r</div><div dir="auto"><br></div><div dir="auto">    ptrCoercion :: Coercion (Ptr a) (Ptr b)</div><div dir="auto">    ptrCoercion = Coercion</div><div dir="auto"><br></div><div dir="auto">I propose that we do this.</div></div>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank" rel="noreferrer">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>
</blockquote></div></div></div>