FluxML / MacroTools.jl

MacroTools provides a library of tools for working with Julia code and expressions.
https://fluxml.ai/MacroTools.jl/stable/
Other
308 stars 77 forks source link

How to escape underscores when matching against macros? #192

Open fatteneder opened 1 year ago

fatteneder commented 1 year ago

It appears to me that the underscore syntax for specifying types and slurping arguments is in conflict when matching against macro calls. Consider the following MWE:

julia> using MacroTools

julia> ex = :(@show f(1))
:(#= REPL[185]:1 =# @show f(1))

julia> MacroTools.@capture(ex, @show args__)
true

julia> args
1-element Vector{Any}:
 :(f(1))

julia> ex = :(@code_warntype f(1))
:(#= REPL[183]:1 =# @code_warntype f(1))

julia> MacroTools.@capture(ex, @code_warntype args__)
false

Indeed, if you look at the @macroexpand output then the _ in code_warntype triggers a MacroTools.TypeBind:

julia> @macroexpand MacroTools.@capture(ex, @code_warntype args__)
quote
    #= /home/florian/.julia/packages/MacroTools/qijNY/src/match/macro.jl:66 =#
    var"@code" = MacroTools.nothing
    args = MacroTools.nothing
    #= /home/florian/.julia/packages/MacroTools/qijNY/src/match/macro.jl:67 =#
    var"#599#env" = MacroTools.trymatch(Core._expr(:macrocall, MacroTools.TypeBind(Symbol("@code"), Set{Any}([:warntype])), $(QuoteNode(:(#= REPL[191]:1 =#))), :args__), ex)
    #= /home/florian/.julia/packages/MacroTools/qijNY/src/match/macro.jl:68 =#
    if var"#599#env" === MacroTools.nothing
        #= /home/florian/.julia/packages/MacroTools/qijNY/src/match/macro.jl:69 =#
        false
    else
        #= /home/florian/.julia/packages/MacroTools/qijNY/src/match/macro.jl:71 =#
        var"@code" = MacroTools.get(var"#599#env", Symbol("@code"), MacroTools.nothing)
        args = MacroTools.get(var"#599#env", :args, MacroTools.nothing)
        #= /home/florian/.julia/packages/MacroTools/qijNY/src/match/macro.jl:72 =#
        true
    end
end

I went through the docs again and realized that there isn't a single example where one matches against a macro. I have been doing this for a while now but only encountered the underscore problem today. Is this kind of matching even supposed to work?


This appears on MacroTools@v0.5.10.

julia> versioninfo()
Julia Version 1.9.0-rc1
Commit 3b2e0d8fbc1 (2023-03-07 07:51 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-14.0.6 (ORCJIT, tigerlake)
  Threads: 1 on 8 virtual cores
Environment:
  LD_PRELOAD = /usr/lib64/libstdc++.so.6
cstjean commented 1 year ago

Yeah, I've bumped into this myself. I'd be interested in seeing a PR for this, but OTOH, I'm reluctant to make changes to the plumbing behind a significant chunk of the ecosystem, in case that we mess it up. I guess we'd have to see if the PR can be simple and "obviously right".