Skip to content

macro replay in JET causes gensym to emit the same symbol twice which causes havoc in ResumableFunctions.jl generated functions #814

Description

@Krastanov

In ResumableFunctions.jl there are a few places where a macro does something akin to this (creating a function with a unique name, "compiling" it, and then looking up its only method as a way to learn something about the type inference that was done):

unique_symbol = gensym()
func_expr = quote
    function $unique_symbol($arg)
        ...
    end
end
func = Core.eval(__module__, func_expr)
... = only(methods(func, Tuple)) # `only` is used here somewhat defensively, because it would not make sense for this unique function to have multiple methods

However, when JET runs its analyzing pass, this macro is executed a second time producing the exact same gensym.

A minimal example is in this repo: https://github.com/Krastanov-agent/gensym-replay-repro/tree/main (a package with about 10 lines of code on which one can run JET and see the crash).

This was noticed in the JET analysis done in CI for QuantumSavory.jl, which depends on ResumableFunctions.jl

It started happening after some fixes that were contributed by @vtjnash in JuliaDynamics/ResumableFunctions.jl#147 -- while the fixes are correct to the best of my knowledge, they unveiled this otherwise latent issue.

Suggested fix in ResumableFunctions.jl in JuliaDynamics/ResumableFunctions.jl#159 (I would appreciate advice on whether the fix is good from someone more experienced).

Most of this was analyzed and reported by codex 5.4, but the entirety of this report is written by me after reading the analysis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions