Ptr operations have the wrong types
Opened this issue · 4 comments
For example,
copyPtrToMutablePrimArray
:: forall m a. (PrimMonad m, Prim a)
=> MutablePrimArray (PrimState m) a
-> Int
-> Ptr a
-> Int
-> m ()
This accepts an arbitrary PrimState m
, but that breaks referential transparency in ST
, since the result of the ST
calculation will depend on what's stored at that address at that time. All operations that dereference Ptr
or Addr
values should require PrimState m ~ RealWorld
.
Okay, it's actually more subtle than that. Sometimes a Ptr
is actually immutable, or treated as such, and copying from it in pure code is fine. But we currently also allow writing to a Ptr
in pure code, which is utterly bogus.
But we currently also allow writing to a
Ptr
in pure code, which is utterly bogus.
Kind of. If you take the address of a pinned MutableByteArray
that's scoped with s
and then write to it, it's fine. Although that seems like a weird way to subvert the type system for no real reason. I'd be fine with a change banned writes to Ptr
in general contexts, but as you point out, we definitely need to be able to copy, particularly because of the existence of primitive string literals and of the internals that back ByteString
.
@andrewthad I think it would make sense to offer an s
-scoped version of Ptr
for that purpose, but I don't think it's at all reasonable to write to a Ptr
in general ST s
. I'd also very much prefer if the "in any state thread" functions that read from Ptr
s had ImmutablePtr
or similar in their names.
So I'd want a copyPtrToMutableByteArray
that works only in RealWorld
, and an otherwise identical copyImmutablePtrToMutableByteArray
(or whatever name) that works in any state thread.