Open ericphanson opened 8 months ago
Nice catch, thanks! The @macroexpand
looks innocent:
julia> @macroexpand @argcheck 1 .== 2
quote
$(Expr(:meta, :begin_optional, ArgCheck.LabelArgCheck()))
begin
var"#264###calle#237" = (.==)
var"#265###arg#235" = 1
var"#266###arg#236" = 2
if var"#264###calle#237"(var"#265###arg#235", var"#266###arg#236")
ArgCheck.nothing
else
ArgCheck.throw_check_error(ArgCheck.CallErrorInfo($(QuoteNode(:(1 .== 2))), ArgCheck.ArgCheckFlavor(), $(QuoteNode(Any[:.==, 1, 2])), [var"#264###calle#237", var"#265###arg#235", var"#266###arg#236"], ()))
end
end
$(Expr(:meta, :end_optional, ArgCheck.LabelArgCheck()))
end
hm, what does that imply?
I can reproduce the error, but I don't know how it arises. I can run var"#264###calle#237" = (.==)
in the REPL just fine.
I think it is either some subtle macro shenanigan or something obvious I am missing.
Hm...
julia> expr = @macroexpand @check 1 .== 2
quote
$(Expr(:meta, :begin_optional, ArgCheck.LabelArgCheck()))
begin
var"#22###calle#236" = (.==)
var"#23###arg#234" = 1
var"#24###arg#235" = 2
if var"#22###calle#236"(var"#23###arg#234", var"#24###arg#235")
ArgCheck.nothing
else
ArgCheck.throw_check_error(ArgCheck.CallErrorInfo($(QuoteNode(:(1 .== 2))), ArgCheck.CheckFlavor(), $(QuoteNode(Any[:.==, 1, 2])), [var"#22###calle#236", var"#23###arg#234", var"#24###arg#235"], ()))
end
end
$(Expr(:meta, :end_optional, ArgCheck.LabelArgCheck()))
end
julia> eval(expr)
ERROR: UndefVarError: `.==` not defined
Stacktrace:
[1] top-level scope
@ :0
[2] eval
@ Core ./boot.jl:385 [inlined]
[3] eval(x::Expr)
@ Base.MainInclude ./client.jl:491
[4] top-level scope
@ REPL[13]:1
julia> expr2 = quote
$(Expr(:meta, :begin_optional, ArgCheck.LabelArgCheck()))
begin
var"#22###calle#236" = (.==)
var"#23###arg#234" = 1
var"#24###arg#235" = 2
if var"#22###calle#236"(var"#23###arg#234", var"#24###arg#235")
ArgCheck.nothing
else
ArgCheck.throw_check_error(ArgCheck.CallErrorInfo($(QuoteNode(:(1 .== 2))), ArgCheck.CheckFlavor(), $(QuoteNode(Any[:.==, 1, 2])), [var"#22###calle#236", var"#23###arg#234", var"#24###arg#235"], ()))
end
end
$(Expr(:meta, :end_optional, ArgCheck.LabelArgCheck()))
end
quote
#= REPL[14]:2 =#
$(Expr(:meta, :begin_optional, ArgCheck.LabelArgCheck()))
#= REPL[14]:3 =#
begin
#= REPL[14]:4 =#
var"#22###calle#236" = (.==)
#= REPL[14]:5 =#
var"#23###arg#234" = 1
#= REPL[14]:6 =#
var"#24###arg#235" = 2
#= REPL[14]:7 =#
if var"#22###calle#236"(var"#23###arg#234", var"#24###arg#235")
#= REPL[14]:8 =#
ArgCheck.nothing
else
#= REPL[14]:10 =#
ArgCheck.throw_check_error(ArgCheck.CallErrorInfo($(QuoteNode(:(1 .== 2))), ArgCheck.CheckFlavor(), $(QuoteNode(Any[:.==, 1, 2])), [var"#22###calle#236", var"#23###arg#234", var"#24###arg#235"], ()))
end
end
#= REPL[14]:13 =#
$(Expr(:meta, :end_optional, ArgCheck.LabelArgCheck()))
end
julia> eval(expr2)
ERROR: CheckError: 1 .== 2 must hold. Got
.== => BroadcastFunction(==)
Stacktrace:
[1] throw_check_error(info::Any)
@ ArgCheck ~/.julia/packages/ArgCheck/CA5vv/src/checks.jl:280
[2] top-level scope
@ REPL[14]:10
[3] eval
@ Core ./boot.jl:385 [inlined]
[4] eval(x::Expr)
@ Base.MainInclude ./client.jl:491
[5] top-level scope
@ REPL[15]:1
Very strange! If I copy the printed version, it works. If I dump
both, I see that .==
has two different representations. In the problematic one (generated by hte macro):
head: Symbol =
args: Array{Any}((2,))
1: Symbol #22###calle#236
2: Symbol .==
vs in the copy-paste printed one:
head: Symbol =
args: Array{Any}((2,))
1: Symbol #22###calle#236
2: Expr
head: Symbol .
args: Array{Any}((1,))
1: Symbol ==
Good work. Now it feels to me this is a macro glitch, would be nice to produce an MWE that does not need ArgCheck.
macro m(code)
esc(code.args[1])
end
@m 1 .== 2
ERROR: LoadError: UndefVarError: `.==` not defined
Stacktrace:
[1] include(fname::String)
@ Base.MainInclude ./client.jl:489
[2] top-level scope
@ REPL[1]:1
in expression starting at /home/jan/doit.jl:5
Opened an issue https://github.com/JuliaLang/julia/issues/53522
Here, the check I wrote is bad since it doesn't return a bool, but the error message is confusing.