Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UndefVarError when using docstring on callable object with return type #1810

Closed
bosonbaas opened this issue May 2, 2022 · 2 comments · Fixed by #1811
Closed

UndefVarError when using docstring on callable object with return type #1810

bosonbaas opened this issue May 2, 2022 · 2 comments · Fixed by #1811

Comments

@bosonbaas
Copy link

The function makedocs(...) seems to fail when the module it is called on a module including docstrings for a callable object with a defined return-type. An example which causes this error is (modified from https://github.com/MatFi/Docerr.jl):

module Docerr

    struct TestStruct
        s1::Int64
        s2::Int64
    end

"""
    function (hw::Struct)(a::Int64, b::Int64)::Int64

This docstring leads to `UndefVarError`
"""
    function (hw::TestStruct)(a::Int64, b::Int64)::Int64
        return hs.s1+hw.s2 +a +b
    end

end

This returns an UndefVarError reproduced below. This error is the same as that produced by MatFi's mwe in #1192, and seems related to #730 as well. A mwe of this error can be generated by using MatFi's repo https://github.com/MatFi/Docerr.jl and replacing src/Docerr.jl with the above code.

ERROR: LoadError: UndefVarError: hw not defined
Stacktrace:
  [1] resolve
    @ ./docs/bindings.jl:20 [inlined]
  [2] category(b::Base.Docs.Binding)
    @ Documenter.DocSystem ~/.julia/packages/Documenter/HmHje/src/DocSystem.jl:261
  [3] runner(#unused#::Type{Documenter.Expanders.AutoDocsBlocks}, x::Markdown.Code, page::Documenter.Documents.Page, doc::Documenter.Documents.Document)
    @ Documenter.Expanders ~/.julia/packages/Documenter/HmHje/src/Expanders.jl:411
  [4] dispatch(::Type{Documenter.Expanders.ExpanderPipeline}, ::Markdown.Code, ::Vararg{Any})
    @ Documenter.Utilities.Selectors ~/.julia/packages/Documenter/HmHje/src/Utilities/Selectors.jl:170
  [5] expand(doc::Documenter.Documents.Document)
    @ Documenter.Expanders ~/.julia/packages/Documenter/HmHje/src/Expanders.jl:42
  [6] runner(#unused#::Type{Documenter.Builder.ExpandTemplates}, doc::Documenter.Documents.Document)
    @ Documenter.Builder ~/.julia/packages/Documenter/HmHje/src/Builder.jl:226
  [7] dispatch(#unused#::Type{Documenter.Builder.DocumentPipeline}, x::Documenter.Documents.Document)
    @ Documenter.Utilities.Selectors ~/.julia/packages/Documenter/HmHje/src/Utilities/Selectors.jl:170
  [8] #2
    @ ~/.julia/packages/Documenter/HmHje/src/Documenter.jl:266 [inlined]
  [9] cd(f::Documenter.var"#2#3"{Documenter.Documents.Document}, dir::String)
    @ Base.Filesystem ./file.jl:110
 [10] #makedocs#1
    @ ~/.julia/packages/Documenter/HmHje/src/Documenter.jl:265 [inlined]
 [11] top-level scope
    @ ~/Documents/work/projects/act/catlab/subobject_utilities/Docerr.jl/docs/make.jl:9
@bosonbaas
Copy link
Author

It should also be noted that documentation compiles correctly if the return type is removed as follows:

function (hw::TestStruct)(a::Int64, b::Int64)
  return hs.s1+hw.s2 +a +b
end

@mortenpi
Copy link
Member

mortenpi commented May 3, 2022

While we could (should) somehow work around this in Documenter, this is actually an upstream issue. The following module

module Docerr
struct TestStruct1 end
struct TestStruct2 end
struct TestStruct3 end

"standard"
(baz::TestStruct1)(a::Int) = 0

"parametric"
(foo::TestStruct2)(a::T) where T = 0

"return"
(bar::TestStruct3)(a::Int, b::Int) :: Int = 0
end

leads to the following docstring metadata:

julia> Docs.meta(Docerr)
IdDict{Any, Any} with 3 entries:
  Main.Docerr.TestStruct1 => MultiDoc(Type[Tuple{Int64}], IdDict{Any, Any}(Tuple{Int64}=>DocStr(svec("standard"), nothing, Dict{Symbol, Any}(:typesig=>Tuple{Int64}, :module=>Main.Docerr, :linenumber=>6, :binding=…
  Main.Docerr.foo         => MultiDoc(Type[Tuple{T} where T], IdDict{Any, Any}(Tuple{T} where T=>DocStr(svec("parametric"), nothing, Dict{Symbol, Any}(:typesig=>Tuple{T} where T, :module=>Main.Docerr, :linenumber…
  Main.Docerr.bar         => MultiDoc(Type[Tuple{Int64, Int64}], IdDict{Any, Any}(Tuple{Int64, Int64}=>DocStr(svec("return"), nothing, Dict{Symbol, Any}(:typesig=>Tuple{Int64, Int64}, :module=>Main.Docerr, :linen…

When using the call syntax with either parametric types or a return type, the docstring gets attached to a "binding" named after the arbitrary variable name in the call syntax. This is why you can actually pull up the docstring from Docerr.foo in the REPL too, even though that makes no sense.

I am not sure we can really fix the metadata on Documenter's end, but I don't think makedocs should be throwing an error in this situation. I think we can print a warning instead if this situation is detected and just not include these docstrings in autodocs.

X-ref: JuliaLang/julia#45174

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants