julia icon indicating copy to clipboard operation
julia copied to clipboard

strange results when searching docstrings by call signatures

Open matthias314 opened this issue 2 years ago • 3 comments

Although it appears not to be documented, one can search docstrings by call signatures. However, the results may be wrong if methods with type parameters are involved. Here is an example:

module M

export f

"doc for f"
function f end

"doc for f(x, y)"
f(x, y) = 1

"doc for f(x::T, y)"
f(x::T, y) where T = one(T)

end

using .M

Then

help?> f(1, 1)
  doc for f(x, y)
----------------------
  doc for f(x::T, y)

as expected (the docstrings for all matching signatures are displayed), but also

help?> f(1)
  doc for f(x::T, y)

which appears wrong.

A look at the entry for f in the META dictionary

julia> first(getfield(M, Docs.META))
Pair{Any, Any}(Main.M.f, Base.Docs.MultiDoc(Type[Union{}, Tuple{Any, Any}, Union{Tuple{T}, Tuple{T, Any}} where T], IdDict{Any, Any}(Union{Tuple{T}, Tuple{T, Any}} where T => Base.Docs.DocStr(svec("doc for f(x::T, y)"), doc for f(x::T, y)
, Dict{Symbol, Any}(:typesig => Union{Tuple{T}, Tuple{T, Any}} where T, :module => Main.M, :linenumber => 11, :binding => Main.M.f, :path => "REPL[1]")), Tuple{Any, Any} => Base.Docs.DocStr(svec("doc for f(x, y)"), doc for f(x, y)
, Dict{Symbol, Any}(:typesig => Tuple{Any, Any}, :module => Main.M, :linenumber => 8, :binding => Main.M.f, :path => "REPL[1]")), Union{} => Base.Docs.DocStr(svec("doc for f"), nothing, Dict{Symbol, Any}(:typesig => Union{}, :module => Main.M, :linenumber => 5, :binding => Main.M.f, :path => "REPL[1]")))))

shows that the call signatures Union{}, Tuple{Any, Any} and Union{Tuple{T}, Tuple{T, Any}} where T are registered. The third one probably causes the strange result above.

I have found the following possibly related docstring in the source code:

https://github.com/JuliaLang/julia/blob/2b2f5344138f2b50ee91132592733743f33c5358/base/docs/Docs.jl#L191-L209

As far as I can tell, the example is correct. However, in the light of my example above, the reason that Tuple{T} appears in Union{Tuple{T, Any}, Tuple{T}} where T seems to be that T is a type parameter and not that f(x::T) is a valid signature. I doubt that this was not intended.

Tested on Julia 1.10.0.

matthias314 avatar Dec 30 '23 00:12 matthias314

This is perhaps related:

julia> NamedTuple{(:a,), Tuple{Int}}(5)
(a = 5,)

help?> NamedTuple{(:a,), Tuple{Int}}(5)
ERROR: syntax: invalid variable expression in "where" around /cache/build/builder-armageddon-4/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/REPL/src/docview.jl:28
Stacktrace:
 [1] top-level scope
   @ none:1

LilithHafner avatar May 10 '24 11:05 LilithHafner

Yes, that's related. It would be fixed by #53824. I didn't check #54324, but I assume it would fix it, too.

matthias314 avatar May 10 '24 12:05 matthias314

Is this a duplicate of https://github.com/JuliaLang/julia/issues/29437? (Edit: It is)

thofma avatar May 10 '24 17:05 thofma