aviatesk / JET.jl

An experimental code analyzer for Julia. No need for additional type annotations.
https://aviatesk.github.io/JET.jl/dev/
MIT License
732 stars 29 forks source link

`report_package` seems to ignore `ignored_modules` #570

Open jakobnissen opened 11 months ago

jakobnissen commented 11 months ago

Example:

julia> report_package(BinBencher; ignored_modules=(AnyFrameModule(Comonicon),))
[ lots of errors found ]

│││┌ install_env_path(m::Module, options::Comonicon.Configs.Comonicon; shell::String, home_dir::String, env::Base.EnvDict, yes::Bool) @ Comonicon.Builder /home/jakob/.julia/dev/Comonicon/src/builder/rcfile.jl:36
││││ no matching method found `contains_fpath(::String, ::typeof(Comonicon.Builder.install_path), ::Base.EnvDict)`: Comonicon.Builder.contains_fpath(rcfile::String, Comonicon.Builder.install_path, env::Base.EnvDict)
│││└────────────────────

So, it looks to me like report_package doesn't work with ignored_modules?

MilesCranmer commented 2 months ago

+1, also seeing this. @aviatesk maybe this is just a missed call somewhere in report_package that forgets to propagate ignored_modules?

MilesCranmer commented 2 months ago

I'm debugging this and it does seem like it actually does module matching on the ignored modules:

struct MyAnyFrameModule; mod::Module; end
function JET.match_module(mod::MyAnyFrameModule, @nospecialize(report::JET.InferenceErrorReport))
    return true
end
JET.test_package(
    DynamicExpressions;
    target_defined_modules=true,
    ignored_modules=(
        MyAnyFrameModule(
            DynamicExpressions.NonDifferentiableDeclarationsModule
        ),
    ),
)

this throws no errors whereas before it did.

Not sure why it's not working though...

MilesCranmer commented 2 months ago

It seems to be because JET puts stuff in a VirtualModule maybe? The linfo of the module it's failing to detect for me looks to be as follows:

JET.linfomod((first(report.vst)).linfo) = Main.var"##JETVirtualModule#575".DynamicExpressions.NonDifferentiableDeclarationsModule

Anyways, here is my current workaround (which works, and also tags submodules)

using DynamicExpressions
struct MyIgnoredModule
    mod::Module
end
function JET.match_module(mod::MyIgnoredModule, @nospecialize(report::JET.InferenceErrorReport))
    s_mod = string(mod.mod)
    any(report.vst) do vst
        occursin(s_mod, string(JET.linfomod(vst.linfo)))
    end
end
JET.test_package(
    DynamicExpressions;
    target_defined_modules=true,
    ignored_modules=(MyIgnoredModule(DynamicExpressions.NonDifferentiableDeclarationsModule),),
)
aviatesk commented 2 months ago

Yes, the problem is that JET's top-level analysis virtualizes the module context of the target file or package (specifically, it's a hack to avoid issues discussed in https://github.com/JuliaLang/julia/issues/40399). Until the fundamental issue is resolved, the string-based matching that @MilesCranmer is doing above is a reasonable workaround, and perhaps JET should automatically do it that way.