Question about how method signatures are encoded in `Docs.Meta`

Hi,
I am trying to debug a surprising behavior in Documenter.jl and had to look at how docstrings are stored and represented internally. I am confused by the encoding that is used to represent method signatures that involve generic type variables.

For example, the following code

module Meta

    "Function"
    function f end

    "Method 1"
    function f(x::Int, y::Int=3) end

    "Method 2"
    function f(x::T, xs::Vector{T}) where T end

end

Docs.meta(Meta)[Docs.Binding(Meta, :f)].docs |> keys

yields this output using Julia 1.30:

Base.KeySet for a IdDict{Any,Any} with 3 entries. Keys:
  Union{}
  Union{Tuple{Int64}, Tuple{Int64,Int64}}
  Union{Tuple{T}, Tuple{T,Array{T,1}}} where T

The encoding for the signature of Method 1 is pretty natural: as the optional argument is desugarized into two methods, we have a union of two tuples with one and two elements respectively.

The encoding for the signature of Method 2 is less natural, as it seems that the union has a different and unusual semantics here. In fact, I would have expected the given encoding to encode
the following signature:

"Method 2 bis"
function f(x::T, xs::Vector{T}=[]) where T end

Instead, the signature of Method 2 bis above is encoded as:

Union{Tuple{T}, Tuple{T}, Tuple{T,Array{T,1}}} where T

Playing with this a bit, it seems that the signature of a method involving n variables is represented as a union whose n first elements are singletons containing those type variables.

Am I correct here and can anyone justify such a convention?

I was not involved in the design of this code, but if I had to guess it would be to support doc retrieval when, e.g., tab-completing in an editor. Again, this is just a guess.

The docsystem still has problems with the where syntax. I think with your Method 2 you are seeing https://github.com/JuliaLang/julia/issues/29437.

1 Like