Macro for generating @NLconstraint

On julia v0.7 and JuMP v0.18:

using JuMP
macro zero_constraint(m, expr)
    quote
        @NLconstraint($(esc(m)), $(esc(expr)) == 0)
    end
end

m = Model()
@variable(m, x)
@variable(m, y)
@zero_constraint(m, x)        #1
@zero_constraint(m, x-y)      #2
@zero_constraint(m, x^3-y)    #3
print(m)

While #1 works, #2 generates:

ERROR: Unexpected object x - y in nonlinear expression.

and #3 generates:

ERROR: Only exponents of 0, 1, or 2 are currently supported. Are you trying to build a nonlinear problem? Make sure you use @NLconstraint/@NLobjective.

It seems that I don’t understand how macro works correctly. Could you help me to figure out what’s happening and how I should modify the @zero_constraint macro? Thanks for your help.

This reflects my situation better.

module MyModule
    import JuMP.@NLconstraint
    export @zero_constraint
    macro zero_constraint(m, expr)
        ex = quote
            @NLconstraint($(esc(m)), $(esc(expr)) == 0)
        end
    end
end
using JuMP, Main.MyModule
model = Model()
@variable(model, x)
@variable(model, y)
@zero_constraint(model, x)
@zero_constraint(model, x-y)
@zero_constraint(model, x^3-y)
print(model)

Those error messages are what you would see if you wrote, e.g.,

model = Model()
@variable(model, x)
@variable(model, y)
expr = x^3 - y
@NLconstraint(model, expr == 0)

So looks like the macro isn’t generating the right code.

Thanks @miles.lubin. It helped me to figure out what was going on. I had some tests:

module MyModule
    import JuMP.@NLconstraint
    export @add_constraints

    macro add_constraints(m)
        ex = quote
            # works in julia v0.7+  /  JuMP v0.18--0.19
            @NLconstraint($(esc(m)), $(esc(:x))^2 == 0)

            # works in julia v0.6 / JuMP v0.18; but not in julia v0.7+
            # @NLconstraint($(esc(m)), $(esc(:(x^2 == 0))))

            # below does not work
            # @NLconstraint($(esc(m)), $(esc(:(x^2))) == 0)
        end
    end
end

using JuMP, Main.MyModule
model = Model()
@variable(model, x)
@add_constraints(model)
print(model)

It seems that how parser works has been changed between julia v0.6 and 0.7+. Unlike in julia v0.6, esc() should be applied to each JuMP variable only, not to the entire expression, in v0.7+. Is there a julia or JuMP function that does this job? I ended up writing such a function, but was wondering any other (and better) option.