Is there a way to capture logging messages (e.g. warnings) issued during compilation, for example from inside a generated function? For example
julia> using Logging
julia> @generated foo() = @warn "this warning is emitted during compilation"
foo (generic function with 1 method)
julia> with_logger(NullLogger()) do; foo(); end
┌ Warning: this warning is emitted during compilation
└ @ Main REPL[18]:1
this doesn’t capture the warning, because it’s emitted before running the body of the do-block, during compilation.
Bonus points for a solution which works with Test.@test_warn.
Very hacky workaround, but one approach would be to use eval or to store the function in an untyped container:
julia> using Logging
julia> @generated foo() = @warn "this warning is emitted during compilation";
julia> with_logger(NullLogger()) do
@eval foo()
end
julia> using Logging
julia> @generated foo() = @warn "this warning is emitted during compilation";
julia> let fv = Ref{Any}(foo)
with_logger(NullLogger()) do
fv[]()
end
end
Both solutions help ensure that foo is not compiled at the same time as the do block.
julia> @generated foo() = @warn "this warning is emitted during compilation"
foo (generic function with 1 method)
julia> @test_warn "this warning is emitted during compilation" @eval foo()
Of course this would fail if the function is called once more:
julia> @test_warn "this warning is emitted during compilation" @eval foo()
Test Failed at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-XG3Q6T6R70.0/build/default-honeycrisp-XG3Q6T6R70-0/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/Test/src/Test.jl:896
Expression: contains_warn(read(fname, String), $(Expr(:escape, "this warning is emitted during compilation")))
ERROR: There was an error during testing
but inside tests execution is generally deterministic, so that shouldn’t be a problem. Need only to see if using @eval in these tests has drawbacks, hopefully not. Thanks!
And of course my hope was ill posed. But wrapping the function in Ref{Any} seems to work well, so I think I’ll go with that solution, thanks!
julia> @testset begin
@generated foo() = @warn "this warning is emitted during compilation"
f = Ref{Any}(foo)
@test_warn "this warning is emitted during compilation" f[]()
end;
Test Summary: | Pass Total Time
test set | 1 1 0.0s