Skip to content

Commit

Permalink
Add more docs and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Mar 3, 2024
1 parent 62ffcfb commit 1f80f17
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Language changes
may pave the way for inference to be able to intelligently re-use the old
results, once the new method is deleted. ([#53415])

- Macro expansion will no longer eargerly recurse into into `Expr(:toplevel)`
expressions returned from macros. Instead, macro expansion of `:toplevel`
expressions will be delayed until evaluation time. This allows a later
expression within a given `:toplevel` expression to make use of macros
defined earlier in the same `:toplevel` expression. ([#53515])

Compiler/Runtime improvements
-----------------------------

Expand Down
46 changes: 46 additions & 0 deletions base/docs/Docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,52 @@ more than one expression is marked then the same docstring is applied to each ex
end
`@__doc__` has no effect when a macro that uses it is not documented.
!!! compat "Julia 1.12"
This section documents a very subtle corner case that is only relevant to
macros which themselves both define other macros and then attempt to use them
within the same expansion. Such macros were impossible to write prior to
Julia 1.12 and are still quite rare. If you are not writing such a macro,
you may ignore this note.
In versions prior to Julia 1.12, macroexpansion would recursively expand through
`Expr(:toplevel)` blocks. This behavior was changed in Julia 1.12 to allow
macros to recursively define other macros and use them in the same returned
expression. However, to preserve backwards compatibility with existing uses of
`@__doc__`, the doc system will still expand through `Expr(:toplevel)` blocks
when looking for `@__doc__` markers. As a result, macro-defining-macros will
have an observable behavior difference when annotated with a docstring:
```julia
julia> macro macroception()
Expr(:toplevel, :(macro foo() 1 end), :(@foo))
end
julia> @macroception
1
julia> "Docstring" @macroception
ERROR: LoadError: UndefVarError: `@foo` not defined in `Main`
```
The supported workaround is to manually expand the `@__doc__` macro in the
defining macro, which the docsystem will recognize and suppress the recursive
expansion:
```julia
julia> macro macroception()
Expr(:toplevel,
macroexpand(__module__, :(@__doc__ macro foo() 1 end); recursive=false),
:(@foo))
end
julia> @macroception
1
julia> "Docstring" @macroception
1
```
"""
:(Core.@__doc__)

Expand Down
12 changes: 12 additions & 0 deletions test/docs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1562,3 +1562,15 @@ Base.@ccallable c51586_long()::Int = 3
@test_broken isempty(undoc)
@test undoc == [Symbol("@var")]
end

# Docing the macroception macro
macro docmacroception()
Expr(:toplevel, macroexpand(__module__, :(@Base.__doc__ macro docmacrofoo() 1 end); recursive=false), :(@docmacrofoo))
end

"""
This docmacroception has a docstring
"""
@docmacroception()

@test Docs.hasdoc(@__MODULE__, :var"@docmacrofoo")

0 comments on commit 1f80f17

Please sign in to comment.