Skip to content

Commit fbdca4d

Browse files
committed
Avoid capturing stacktrace, just use rethrow instead
1 parent 51a2002 commit fbdca4d

File tree

2 files changed

+18
-24
lines changed

2 files changed

+18
-24
lines changed

src/macro_expansion.jl

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,13 @@ struct MacroExpansionError
7979
ex::SyntaxTree
8080
msg::String
8181
position::Symbol
82-
stacktrace::Vector{Base.StackTraces.StackFrame}
8382
end
8483

8584
"""
8685
`position` - the source position relative to the node - may be `:begin` or `:end` or `:all`
8786
"""
8887
function MacroExpansionError(ex::SyntaxTree, msg::AbstractString; position=:all)
89-
MacroExpansionError(nothing, ex, msg, position, scrub_expand_macro_stacktrace(stacktrace(backtrace())))
90-
end
91-
92-
function scrub_expand_macro_stacktrace(stacktrace::Vector{Base.StackTraces.StackFrame})
93-
idx = @something findfirst(stacktrace) do stackframe::Base.StackTraces.StackFrame
94-
stackframe.func === :expand_macro && stackframe.file === Symbol(@__FILE__)
95-
end error("`scrub_expand_macro_stacktrace` is expected to be called from `expand_macro`")
96-
return stacktrace[1:idx-1]
88+
MacroExpansionError(nothing, ex, msg, position)
9789
end
9890

9991
function Base.showerror(io::IO, exc::MacroExpansionError)
@@ -156,12 +148,13 @@ function expand_macro(ctx::MacroExpansionContext, ex::SyntaxTree)
156148
# TODO: Allow invoking old-style macros for compat
157149
invokelatest(macfunc, macro_args...)
158150
catch exc
151+
# TODO: Using rethrow() is kinda ugh. Is there a way to avoid it?
152+
# NOTE: Although currently rethrow() is necessary to allow outside catchers to access full stacktrace information
159153
if exc isa MacroExpansionError
160154
# Add context to the error.
161-
# TODO: Using rethrow() is kinda ugh. Is there a way to avoid it?
162-
rethrow(MacroExpansionError(mctx, exc.ex, exc.msg, exc.position, exc.stacktrace))
155+
rethrow(MacroExpansionError(mctx, exc.ex, exc.msg, exc.position))
163156
else
164-
throw(MacroExpansionError(mctx, ex, "Error expanding macro", :all, scrub_expand_macro_stacktrace(stacktrace(catch_backtrace()))))
157+
rethrow(MacroExpansionError(mctx, ex, "Error expanding macro", :all))
165158
end
166159
end
167160

test/macros.jl

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,27 +150,28 @@ macro m_throw(x)
150150
:(\$(f_throw(x)))
151151
end
152152
""")
153-
let ret = try
153+
let (err, st) = try
154154
JuliaLowering.include_string(test_mod, "_never_exist = @m_throw 42")
155-
catch err
156-
err
155+
catch e
156+
e, stacktrace(catch_backtrace())
157157
end
158-
@test ret isa JuliaLowering.MacroExpansionError
159-
@test length(ret.stacktrace) == 2
160-
@test ret.stacktrace[1].func === :f_throw
161-
@test ret.stacktrace[2].func === Symbol("@m_throw")
158+
@test err isa JuliaLowering.MacroExpansionError
159+
# Check that `catch_backtrace` can capture the stacktrace of the macro functions
160+
@test any(sf->sf.func===:f_throw, st)
161+
@test any(sf->sf.func===Symbol("@m_throw"), st)
162162
end
163163

164164
include("ccall_demo.jl")
165165
@test JuliaLowering.include_string(CCall, "@ccall strlen(\"foo\"::Cstring)::Csize_t") == 3
166-
let ret = try
166+
let (err, st) = try
167167
JuliaLowering.include_string(CCall, "@ccall strlen(\"foo\"::Cstring)")
168168
catch e
169-
e
169+
e, stacktrace(catch_backtrace())
170170
end
171-
@test ret isa JuliaLowering.MacroExpansionError
172-
@test ret.msg == "Expected a return type annotation like `::T`"
173-
@test any(sf->sf.func===:ccall_macro_parse, ret.stacktrace)
171+
@test err isa JuliaLowering.MacroExpansionError
172+
@test err.msg == "Expected a return type annotation like `::T`"
173+
# Check that `catch_backtrace` can capture the stacktrace of the macro function
174+
@test any(sf->sf.func===:ccall_macro_parse, st)
174175
end
175176

176177
end # module macros

0 commit comments

Comments
 (0)