Skip to content

Ptr doesn't observe the supertype semantics of Ref #49004

@Seelengrab

Description

@Seelengrab

I've stumbled across this unfortunate inconsistency:

help?> Ptr
search: Ptr Cptrdiff_t CapturedException splitdrive pointer pointer_from_objref escape_string splitdir

  Ptr{T}

  A memory address referring to data of type T. However, there is no guarantee that the memory is actually valid,
  or that it actually represents data of the specified type.

julia> supertype(Ptr)
Ref

help?> Ref
search: Ref WeakRef prevfloat chopprefix UndefRefError GlobalRef uppercasefirst lowercasefirst

  Ref{T}

  An object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated
  memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as
  the Ref itself is referenced.

[...]

In essence, we document that Ref{T} is guaranteed to point to valid julia allocated memory, which is not at all true of Ptr{T}, but Ptr{T} <: Ref{T} still holds. There are other problems, like Ptr not having getindex defined, as the Ref docstring claims:

julia> a = [1,2,3];

julia> p = pointer(a)
Ptr{Int64} @0x00007fe5bfbfc9f0

julia> p[]
ERROR: MethodError: no method matching getindex(::Ptr{Int64})

So at minimum, Ptr doesn't fulfill the API guaranteed by Ref{T} per the docstring.

We could change the docstring of Ref to Ref(x), and mention that the Ref abstract type does not make such a guarantee. Another option would be to change the name of the Ref type to something else (AbstractRef?) and only keep the Ref function/type around as a shorthand for RefValue, which is what it does now anyway (see @edit Ref(1)). To keep the API the same, it would change from this:

  • Ref{T}
    • Ptr{T}
    • RefValue{T}
    • RefArray{T}

to this:

  • AbstractRef{T}
    • Ptr{T}
    • Ref{T}
      • RefValue{T}
      • RefArray{T}

The issue with that is that we don't know whether someone relies on Ptr{T} <: Ref{T} somewhere (which they shouldn't, I think).

Metadata

Metadata

Assignees

No one assigned

    Labels

    correctness bug ⚠Bugs that are likely to lead to incorrect results in user code without throwing

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions