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

Confusing UndefVarError error #44

Open
ericphanson opened this issue Feb 28, 2024 · 8 comments
Open

Confusing UndefVarError error #44

ericphanson opened this issue Feb 28, 2024 · 8 comments

Comments

@ericphanson
Copy link

julia> using ArgCheck

julia> [1] .== [2]
1-element BitVector:
 0

julia> @check [1] .== [2]
ERROR: UndefVarError: `.==` not defined
Stacktrace:
 [1] top-level scope
   @ REPL[111]:1

Here, the check I wrote is bad since it doesn't return a bool, but the error message is confusing.

@jw3126
Copy link
Owner

jw3126 commented Feb 28, 2024

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

@ericphanson
Copy link
Author

hm, what does that imply?

@jw3126
Copy link
Owner

jw3126 commented Feb 28, 2024

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.

@jw3126
Copy link
Owner

jw3126 commented Feb 28, 2024

I think it is either some subtle macro shenanigan or something obvious I am missing.

@ericphanson
Copy link
Author

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 ==

@jw3126
Copy link
Owner

jw3126 commented Feb 29, 2024

Good work. Now it feels to me this is a macro glitch, would be nice to produce an MWE that does not need ArgCheck.

@jw3126
Copy link
Owner

jw3126 commented Feb 29, 2024

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

@jw3126
Copy link
Owner

jw3126 commented Feb 29, 2024

Opened an issue JuliaLang/julia#53522

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

No branches or pull requests

2 participants