Giter Site home page Giter Site logo

aviatesk / jet.jl Goto Github PK

View Code? Open in Web Editor NEW
693.0 9.0 28.0 17.02 MB

An experimental code analyzer for Julia. No need for additional type annotations.

Home Page: https://aviatesk.github.io/JET.jl/dev/

License: MIT License

Julia 100.00%
julia static-analysis error-detection performance-engineering

jet.jl's Introduction

JET.jl

JET employs Julia's type inference system to detect potential bugs and type instabilities.

‼️ JET is tightly coupled to the Julia compiler, and so each JET release supports a limited range of Julia versions. See the Project.toml file for the range of supported Julia versions. The Julia package manager should install a version of JET compatible with the Julia version you are running. If you want to use JET on unreleased version of Julia where compatibility with JET is yet unknown, clone this git repository and dev it, such that Julia compatibility is ignored.

‼️ Also note that the tight coupling of JET and the Julia compiler means that JET results can vary depending on your Julia version. In general, the newer your Julia version is, the more accurately and quickly you can expect JET to analyze your code, assuming the Julia compiler keeps evolving all the time from now on.

Quickstart

See more commands, options and explanations in the documentation.

Installation

JET is a standard Julia package. So you can just install it via Julia's built-in package manager and use it just like any other package:

julia> using Pkg; Pkg.add("JET")
[ some output elided ]

julia> using JET

Detect type instability with @report_opt

Type instabilities can be detected in function calls using the @report_opt macro, which works similar to the @code_warntype macro. Note that, because JET relies on Julia's type inference, if a chain of inference is broken due to dynamic dispatch, then all downstream function calls will be unknown to the compiler, and so JET cannot analyze them.

julia> @report_opt foldl(+, Any[]; init=0)
═════ 2 possible errors found ═════
┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(foldl), op::typeof(+), itr::Vector{Any}) @ Base ./reduce.jl:198
│┌ foldl(op::typeof(+), itr::Vector{Any}; kw::@Kwargs{init::Int64}) @ Base ./reduce.jl:198
││┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(mapfoldl), f::typeof(identity), op::typeof(+), itr::Vector{Any}) @ Base ./reduce.jl:175
│││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Any}; init::Int64) @ Base ./reduce.jl:175
││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(+), nt::Int64, itr::Vector{Any}) @ Base ./reduce.jl:44
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Int64, itr::Vector{Any}) @ Base ./reduce.jl:48
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Int64, itr::Vector{Any}) @ Base ./reduce.jl:58
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Int64, x::Any) @ Base ./reduce.jl:86
││││││││ runtime dispatch detected: +(acc::Int64, x::Any)::Any
│││││││└────────────────────
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Int64, itr::Vector{Any}) @ Base ./reduce.jl:62
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Any, x::Any) @ Base ./reduce.jl:86
││││││││ runtime dispatch detected: +(acc::Any, x::Any)::Any
│││││││└────────────────────

Detect type errors with @report_call

This works best on type stable code, so use @report_opt liberally before using @report_call.

julia> @report_call foldl(+, Char[])
═════ 2 possible errors found ═════
┌ foldl(op::typeof(+), itr::Vector{Char}) @ Base ./reduce.jl:198
│┌ foldl(op::typeof(+), itr::Vector{Char}; kw::@Kwargs{}) @ Base ./reduce.jl:198
││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Char}) @ Base ./reduce.jl:175
│││┌ mapfoldl(f::typeof(identity), op::typeof(+), itr::Vector{Char}; init::Base._InitialValue) @ Base ./reduce.jl:175
││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(+), nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:44
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:48
││││││┌ _foldl_impl(op::Base.BottomRF{typeof(+)}, init::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:62
│││││││┌ (::Base.BottomRF{typeof(+)})(acc::Char, x::Char) @ Base ./reduce.jl:86
││││││││ no matching method found `+(::Char, ::Char)`: (op::Base.BottomRF{typeof(+)}).rf::typeof(+)(acc::Char, x::Char)
│││││││└────────────────────
│││││┌ foldl_impl(op::Base.BottomRF{typeof(+)}, nt::Base._InitialValue, itr::Vector{Char}) @ Base ./reduce.jl:49
││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(+)}, itr::Vector{Char}) @ Base ./reduce.jl:383
│││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(+)}, itr::Vector{Char}, ::Base.HasEltype) @ Base ./reduce.jl:384
││││││││┌ reduce_empty(op::Base.BottomRF{typeof(+)}, ::Type{Char}) @ Base ./reduce.jl:360
│││││││││┌ reduce_empty(::typeof(+), ::Type{Char}) @ Base ./reduce.jl:343
││││││││││ no matching method found `zero(::Type{Char})`: zero(T::Type{Char})
│││││││││└────────────────────

Analyze packages with report_package

This looks for all method definitions and analyses function calls based on their signatures. Note that this is less accurate than @report_call, because the actual input types cannot be known for generic methods.

julia> using Pkg; Pkg.activate(; temp=true, io=devnull); Pkg.add("AbstractTrees"; io=devnull);

julia> Pkg.status()
Status `/private/var/folders/xh/6zzly9vx71v05_y67nm_s9_c0000gn/T/jl_h07K2m/Project.toml`
  [1520ce14] AbstractTrees v0.4.4

julia> report_package("AbstractTrees")
[ some output elided ]
═════ 7 possible errors found ═════
┌ isroot(root::Any, x::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/base.jl:102
│ no matching method found `parent(::Any, ::Any)`: AbstractTrees.parent(root::Any, x::Any)
└────────────────────
┌ AbstractTrees.IndexNode(tree::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:117
│ no matching method found `rootindex(::Any)`: rootindex(tree::Any)
└────────────────────
┌ parent(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:127
│ no matching method found `parentindex(::Any, ::Any)`: pidx = parentindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ nextsibling(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:132
│ no matching method found `nextsiblingindex(::Any, ::Any)`: sidx = nextsiblingindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ prevsibling(idx::AbstractTrees.IndexNode) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/indexing.jl:137
│ no matching method found `prevsiblingindex(::Any, ::Any)`: sidx = prevsiblingindex((idx::AbstractTrees.IndexNode).tree::Any, (idx::AbstractTrees.IndexNode).index::Any)
└────────────────────
┌ prevsibling(csr::AbstractTrees.IndexedCursor) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/cursors.jl:234
│ no matching method found `getindex(::Nothing, ::Int64)` (1/2 union split): (AbstractTrees.parent(csr::AbstractTrees.IndexedCursor)::Union{Nothing, AbstractTrees.IndexedCursor})[idx::Int64]
└────────────────────
┌ (::AbstractTrees.var"#17#18")(n::Any) @ AbstractTrees ~/.julia/packages/AbstractTrees/EUx8s/src/iteration.jl:323
│ no matching method found `parent(::Any, ::Any)`: AbstractTrees.parent(getfield(#self#::AbstractTrees.var"#17#18", :tree)::Any, n::Any)
└────────────────────

Limitations

JET explores the functions you call directly as well as their inferable callees. However, if the argument types for a call cannot be inferred, JET does not analyze the callee. Consequently, a report of No errors detected does not imply that your entire codebase is free of errors. To increase the confidence in JET's results use @report_opt to make sure your code is inferrible.

JET integrates with SnoopCompile, and you can sometimes use SnoopCompile to collect the data to perform more comprehensive analyses. SnoopCompile's limitation is that it only collects data for calls that have not been previously inferred, so you must perform this type of analysis in a fresh session.

See SnoopCompile's JET-integration documentation for further details.

Acknowledgement

This project started as my undergrad thesis project at Kyoto University, supervised by Prof. Takashi Sakuragawa. We were heavily inspired by ruby/typeprof, an experimental type understanding/checking tool for Ruby. The grad thesis about this project is published at https://github.com/aviatesk/grad-thesis, but currently, it's only available in Japanese.

jet.jl's People

Contributors

aviatesk avatar dilumaluthge avatar dpinol avatar fredrikekre avatar goerch avatar goggle avatar gunnarfarneback avatar jakobnissen avatar nsajko avatar pfitzseb avatar simonbyrne avatar svilupp avatar timholy avatar whojo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jet.jl's Issues

Handle multithreading

Small example:

using JET
foo() = fetch(Threads.@spawn 1 + "foo")
@report_call foo()

Output:

julia> @report_call foo()
No errors !
Any

false positives on kwargs method

mre:

f(a; b = nothing, c = nothing) = return
interp, frame = TypeProfiler.profile_call(Any) do b
    f(1; b)
end
TypeProfiler.print_reports(stdout, interp.reports)
═════ 1 possible error found ═════
┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/test/test_abstractinterpretation.jl:343 Core.kwfunc(Main.f)(Core.apply_type(Core.NamedTuple, (:b,))(Core.tuple(b)), Main.f, 1)
│┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/test/test_abstractinterpretation.jl:341 Base.getindex(_2, :c)
││┌ @ namedtuple.jl:116 Base.getfield(t, i)
│││ invalid builtin function call: Base.getfield(t::NamedTuple{(:b,), _A} where _A<:Tuple{Any}, i::Symbol)
││└─────────────────────

performance problem in #65

I just found inference sometimes never terminates on #65...
It seems to happen when QuoteNode or Expr come to be argument; e.g.

julia> @report_call println(QuoteNode(10)) # will never terminate

It doesn't seem that (frame::InferenceState).parent traversal causes this, since the same problem happens for #69 as well.

profiling performance

this script can be used as benchmark:

using TypeProfiler, StatsPlots

@info "warm up"
@time @profile_call rand(100)

@info "profiling on density (first time)"
@time @profile_call density(rand(100)) # can be slow ...

@info "profiling on density (second time)"
@time @profile_call density(rand(100)) # second time (simulates watch mode), still slow ...

This script currently runs in the following insane amount of time (from f358c80)

[ Info: warm up
No errors !
  3.850066 seconds (2.82 M allocations: 156.512 MiB, 0.66% gc time)

[ Info: profiling on density (first time)
═════ 30 possible errors found ═════
┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:402 Plots.#density#363(Core.tuple(Base.pairs(Core.NamedTuple()), #self#), args...)
│┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:402 Core.kwfunc(RecipesBase.plot)(Core.tuple(Base.merge(Base.merge(Base.NamedTuple(), kw), Core.apply_type(Core.NamedTuple, (:seriestype,))((:density,))), RecipesBase.plot), args...)
││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:51 Plots.#plot#129(Core.tuple(kw..., _3), args...)
│││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:55 Plots.Plot()
││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/types.jl:81 Plots.backend()
│││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:162 Plots._pick_default_backend()
││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:143 Plots.backend(sym)
│││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:184 Plots.backend(Plots._backend_instance(sym))
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:178 Base.setproperty!(Plots.CURRENT_BACKEND, :pkg, pkg)
│││││││││┌ @ Base.jl:34 Base.convert(Base.fieldtype(Base.typeof(x), f), v)
││││││││││ for one of the union split cases, no matching method found for signature: Base.convert(Base.fieldtype(Base.typeof(x::Plots.CurrentBackend)::Type{Plots.CurrentBackend}, f::Symbol)::Union{Type{Symbol}, Type{AbstractBackend}}, v::AbstractBackend)
│││││││││└──────────────
│││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:57 Plots._plot!(plt, plotattributes, args)
││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:167 RecipesPipeline.recipe_pipeline!(plt, plotattributes, args)
│││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/RecipesPipeline.jl:69 RecipesPipeline._process_userrecipes!(plt, plotattributes, args)
││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/user_recipe.jl:33 RecipesPipeline._finish_userrecipe!(plt, kw_list, next_series)
│││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/user_recipe.jl:99 RecipesPipeline.preprocess_attributes!(plt, kw)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/pipeline.jl:70 RecipesPipeline.preprocess_attributes!(plotattributes)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/args.jl:975 Plots.replaceAliases!(plotattributes, Plots._keyAliases)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:202 Plots.keys(plotattributes)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/container_loops.jl:233 DataStructures.SDMKeyIteration(ba)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/container_loops.jl:114 Core.apply_type(DataStructures.SDMKeyIteration, _)(base)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/container_loops.jl:114 Base.convert(_, base)
││││││││││││││┌ @ abstractdict.jl:518 _(x)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/sorted_dict.jl:119 Core.apply_type(DataStructures.SortedDict, _, _)(DataStructures.Forward, kv)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/sorted_dict.jl:124 DataStructures.not_iterator_of_pairs(kv)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/dict_support.jl:6 DataStructures.any(#61, Base.vect(DataStructures.iterate))
││││││││││││││││││┌ @ reducedim.jl:880 Base.#any#673(Base.:, #self#, f, a)
│││││││││││││││││││┌ @ reducedim.jl:880 Base._any(f, a, dims)
││││││││││││││││││││┌ @ reduce.jl:876 f(x)
│││││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/dict_support.jl:6 DataStructures.methodswith(DataStructures.typeof(Core.getfield(#self#, :kv)), x, true)
││││││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/InteractiveUtils/src/InteractiveUtils.jl:138 InteractiveUtils.#methodswith#62(false, #self#, t, f, meths)
│││││││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/InteractiveUtils/src/InteractiveUtils.jl:148 InteractiveUtils.push!(meths, d)
││││││││││││││││││││││││ no matching method found for call signature: InteractiveUtils.push!(meths::Bool, d::Method)
│││││││││││││││││││││││└────────────────────────────────────────────────────────────────────────────────────────────────────────
│││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/RecipesPipeline.jl:80 RecipesPipeline._process_plotrecipes!(plt, kw_list)
││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/plot_recipe.jl:16 RecipesPipeline._process_plotrecipe(plt, next_kw, kw_list, still_to_process)
│││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/plot_recipe.jl:31 RecipesBase.apply_recipe(kw, Core.apply_type(RecipesPipeline.Val, st), plt)
││││││││┌ @ /Users/aviatesk/.julia/packages/StatsPlots/6bINV/src/marginalhist.jl:9 Plots._hist_edges(Core.tuple(x, y), bns)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:718 Plots.map(#186, Core.tuple(Plots.:(1, _)...))
││││││││││┌ @ tuple.jl:180 f(Base.getindex(t, 1))
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:719 Plots._hist_edge(Core.getfield(#self#, :vs), dim, Base.getindex(Core.getfield(#self#, :binning), dim))
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:708 StatsBase.histrange(Base.getindex(vs, dim), binning, :left)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/StatsBase/ZxhK8/src/hist.jl:39 StatsBase.histrange(F(lo), F(hi), n, closed)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/StatsBase/ZxhK8/src/hist.jl:99 Base.floatrange(start, step, len, divisor)
│││││││││││││││┌ @ twiceprecision.jl:378 Base.floatrange(T, ia, ist, Base.Int(len), idivisor)
││││││││││││││││┌ @ twiceprecision.jl:361 Base.steprangelen_hp(_, Core.tuple(start_n, den), Core.tuple(step_n, den), 0, Base.Int(len), 1)
│││││││││││││││││┌ @ twiceprecision.jl:323 Core.apply_type(Base.TwicePrecision, Base.Float64)(step, nb)
││││││││││││││││││┌ @ twiceprecision.jl:185 Base.convert(_, hi)
│││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Float64}, hi::Tuple{Integer, Integer})
││││││││││││││││││└─────────────────────────
││││││││││││││││┌ @ twiceprecision.jl:368 Base.steprangelen_hp(_, Core.tuple(ref_n, den), Core.tuple(step_n, den), nb, Base.Int(len), imin)
│││││││││││││││││┌ @ twiceprecision.jl:323 Core.apply_type(Base.TwicePrecision, Base.Float64)(step, nb)
││││││││││││││││││┌ @ twiceprecision.jl:185 Base.convert(_, hi)
│││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Float64}, hi::Tuple{Integer, Integer})
││││││││││││││││││└─────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:953 Plots.xlims(Base.getindex(Base.getproperty(plt, :subplots), sp_index))
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:419 Plots.xlims(Plots.current(), sp_idx)
││││││││││ for one of the union split cases, no matching method found for signature: Plots.xlims(Plots.current()::Union{Nothing, AbstractPlot}, sp_idx::Int64)
│││││││││└────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:956 Plots.ylims(Base.getindex(Base.getproperty(plt, :subplots), sp_index))
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:420 Plots.ylims(Plots.current(), sp_idx)
││││││││││ for one of the union split cases, no matching method found for signature: Plots.ylims(Plots.current()::Union{Nothing, AbstractPlot}, sp_idx::Int64)
│││││││││└────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:997 Plots.merge(plotattributes, Plots.copy(Base.getproperty(series, :plotattributes)))
│││││││││┌ @ abstractdict.jl:306 Base.merge!(Core.tuple(Base._typeddict(Core.tuple(d), others...)), others...)
││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/priorityqueue.jl:361 DataStructures.iterate(other, false)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/priorityqueue.jl:401 DataStructures.copy(Base.getproperty(pq, :index))
││││││││││││┌ @ dict.jl:120 Base.Dict(d)
│││││││││││││┌ @ dict.jl:129 Base.dict_with_eltype(#266, kv, Base.eltype(kv))
││││││││││││││┌ @ abstractdict.jl:530 DT_apply(_, _)(kv)
│││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Pkg/src/manifest.jl:139 Pkg.Types.get(info, "pinned", Pkg.Types.nothing)
││││││││││││││││ no matching method found for call signature: Pkg.Types.get(info::Int64, "pinned", Pkg.Types.nothing)
│││││││││││││││└───────────────────────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:319 RecipesBase.RecipeData(plotattributes, RecipesBase.wrap_tuple(args))
│││││││││┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:57 Base.convert(Core.fieldtype(RecipesBase.RecipeData, 1), plotattributes)
││││││││││┌ @ abstractdict.jl:518 _(x)
│││││││││││ no matching method found for call signature: _::Type{AbstractDict{Symbol, Any}}(x::Dict{_A, _B} where _B where _A)
││││││││││└───────────────────────
│││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/RecipesPipeline.jl:96 RecipesPipeline._process_seriesrecipes!(plt, kw_list)
││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/series_recipe.jl:25 RecipesPipeline._process_seriesrecipe(plt, series_attr)
│││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/series_recipe.jl:44 RecipesPipeline.add_series!(plt, plotattributes)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/pipeline.jl:314 Plots._add_the_series(plt, sp, plotattributes)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/pipeline.jl:371 Plots.warn_on_unsupported_args(Base.getproperty(plt, :backend), plotattributes)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/args.jl:1162 Base.iterate(Plots.keys(plotattributes))
│││││││││││┌ @ abstractdict.jl:60 Base.iterate(Core.tuple(Base.getproperty(v, :dict)), state...)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/utils.jl:38 RecipesPipeline.collect(Base.getproperty(RecipesPipeline.Iterators, :flatten)(Core.tuple(exp_keys, def_keys)))
│││││││││││││┌ @ array.jl:624 Base._collect(Base.:(1, 1), itr, Base.IteratorEltype(itr), Base.IteratorSize(itr))
││││││││││││││┌ @ array.jl:635 Base.iterate(itr)
│││││││││││││││┌ @ iterators.jl:1089 #self#(f, ())
││││││││││││││││┌ @ iterators.jl:1097 Base.Iterators.iterate(Base.getproperty(f, :it), Base.getindex(x, 2))
│││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.Iterators.iterate(Base.getproperty(f::Base.Iterators.Flatten{Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}}, :it::Symbol)::Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Base.getindex(x::Union{Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Int64}, Tuple{Set{Symbol}, Int64}}, 2)::Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}})
││││││││││││││││└─────────────────────
││││││││││││││┌ @ array.jl:636 Base.iterate(itr, Core.getfield(_6, 2))
│││││││││││││││┌ @ iterators.jl:1093 Base.Iterators.iterate(Base.getproperty(f, :it), Base.getindex(state, 1))
││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.Iterators.iterate(Base.getproperty(f::Base.Iterators.Flatten{Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}}, :it::Symbol)::Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Base.getindex(state::Tuple{Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Int64}, 1)::Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}})
│││││││││││││││└─────────────────────
││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:169 Plots._do_plot_show(plt, Base.getindex(plt, :show))
│││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:153 Plots.gui(plt)
││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:139 Plots.display(Plots.PlotsDisplay(), plt)
│││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:149 Plots.prepare_output(plt)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:186 Plots._update_min_padding!(sp)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:713 Plots.get_ticks(sp, xaxis)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:217 Plots.#get_ticks#110(true, #self#, sp, axis)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:241 Plots.optimal_ticks_and_labels(sp, axis)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:135 #self#(sp, axis, Plots.nothing)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:156 Core.kwfunc(Plots.optimize_datetime_ticks)(Core.apply_type(Core.NamedTuple, (:k_min, :k_max))(Core.tuple(2, 4)), Plots.optimize_datetime_ticks, Plots.*(8.64e7, amin), Plots.*(8.64e7, amax))
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:463 PlotUtils.#optimize_datetime_ticks#57(k_min, k_max, _3, a_min, a_max)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:463 PlotUtils.DateTime(Base.getproperty(PlotUtils.Dates, :UTM)(PlotUtils.Int64(PlotUtils.round(a_min))))
││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:383 #self#(y, 1, 1, 0, 0, 0, 0, Dates.TWENTYFOURHOUR)
│││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:383 Dates.Int64(y)
││││││││││││││││││ no matching method found for call signature: Dates.Int64(y::Dates.UTInstant)
│││││││││││││││││└──────────────────────────────────────────────────────────────────────────────────
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:496 PlotUtils.collect(PlotUtils.:(start, steplength, x_max))
││││││││││││││││┌ @ range.jl:991 Base.vcat(r)
│││││││││││││││││┌ @ range.jl:983 Base.iterate(ra)
││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Dates/src/ranges.jl:59 Dates.length(r)
│││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/FixedPointNumbers/HAGk2/src/FixedPointNumbers.jl:251 Base.getproperty(r, :start)
││││││││││││││││││││┌ @ Base.jl:33 Base.getfield(x, f)
│││││││││││││││││││││ invalid builtin function call: Base.getfield(x::StepRange{Union{}, Union{}}, f::Symbol)
││││││││││││││││││││└──────────────
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:167 Core.kwfunc(Plots.optimize_ticks)(Core.apply_type(Core.NamedTuple, (:k_min, :k_max))(Core.tuple(4, 8)), Plots.optimize_ticks, sf(amin), sf(amax))
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:305 PlotUtils.#optimize_ticks#52(extend_ticks, k_min, k_max, scale, granularity_weight, simplicity_weight, coverage_weight, niceness_weight, strict_span, span_buffer, _3, x_min, x_max)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:305 Core.kwfunc(PlotUtils.optimize_ticks)(Core.apply_type(Core.NamedTuple, (:extend_ticks, :scale))(Core.tuple(extend_ticks, scale)), PlotUtils.optimize_ticks, PlotUtils.convert(PlotUtils.DateTime, x_min), PlotUtils.convert(PlotUtils.DateTime, x_max))
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:315 PlotUtils.#optimize_ticks#53(extend_ticks, k_min, k_max, scale, granularity_weight, simplicity_weight, coverage_weight, niceness_weight, strict_span, span_buffer, _3, x_min, x_max)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:408 Base.iterate(ticks, Core.getfield(_26, 2))
││││││││││││││││││┌ @ array.jl:785 Base.%(i, Base.UInt)
│││││││││││││││││││ no matching method found for call signature: Base.%(i::Tuple{Base.OneTo{Int64}, Int64}, Base.UInt)
││││││││││││││││││└────────────────
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:408 Base.iterate(ticks, Core.getfield(_26, 2))
││││││││││││││││││┌ @ array.jl:785 Base.%(i, Base.UInt)
│││││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.%(i::Union{Int64, Tuple{Base.OneTo{Int64}, Int64}, Tuple{Int64, Nothing}}, Base.UInt)
││││││││││││││││││└────────────────
││││││││││││││││││┌ @ array.jl:785 Base.+(i, 1)
│││││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.+(i::Union{Int64, Tuple{Base.OneTo{Int64}, Int64}, Tuple{Int64, Nothing}}, 1)
││││││││││││││││││└────────────────
│││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:150 Plots._display(plt)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:949 Plots.standalone_html_window(plt)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:49 Plots.write_temp_html(plt)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:36 Core.kwfunc(Plots.standalone_html)(Core.apply_type(Core.NamedTuple, (:title,))(Core.tuple(Base.getindex(Base.getproperty(plt, :attr), :window_title))), Plots.standalone_html, plt)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:7 Plots.#standalone_html#346(title, _3, plt)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:7 Plots.html_body(plt)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:873 Plots.plotly_html_body(plt)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:903 #self#(plt, Plots.nothing)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:908 Plots.plotly_series_json(plt)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:868 Plots.plotly_series(plt)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:862 Plots.plotly_series(plt, series)
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:507 Plots.plotly_series_shapes(plt, series, clims)
│││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:635 Plots.iter_segments(series)
││││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:88 Plots.push!(segs, seg)
│││││││││││││││││││││┌ @ array.jl:934 Base.convert(_, item)
││││││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:58 _(f)
│││││││││││││││││││││││ no matching method found for call signature: _::Type{UnitRange{Int64}}(f::LinearAlgebra.Factorization)
││││││││││││││││││││││└─────────────────────────────────────────────────────────────────────────────────────────────────
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:569 Plots.KW(Plots.=>(:show, true), Plots.=>(:color, Plots.rgba_string(Plots.plot_color(Base.getindex(series, :linecolor), Base.getindex(series, :linealpha)))), Plots.=>(:highlightwidth, Base.getindex(series, :linewidth)))
│││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
│││││││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.convert(_::Type{Symbol}, key0::Union{Bool, String, Symbol})
││││││││││││││││││││└───────────────
│││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
│││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Bool)
││││││││││││││││││││└───────────────
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:616 Base.broadcasted(Plots.get_markercolor, series, inds)
│││││││││││││││││││┌ @ broadcast.jl:1260 Base.Broadcast.broadcastable(arg1)
││││││││││││││││││││┌ @ broadcast.jl:682 Base.Broadcast.collect(x)
│││││││││││││││││││││┌ @ array.jl:624 Base._collect(Base.:(1, 1), itr, Base.IteratorEltype(itr), Base.IteratorSize(itr))
││││││││││││││││││││││┌ @ array.jl:630 Base._similar_for(cont, Base.eltype(itr), itr, isz)
│││││││││││││││││││││││┌ @ array.jl:597 Base.length(itr)
││││││││││││││││││││││││ no matching method found for call signature: Base.length(itr::Plots.Series)
│││││││││││││││││││││││└────────────────
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:908 Plots.plotly_layout_json(plt)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:382 Plots.plotly_layout(plt)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:245 Plots.plotly_annotation_dict(titlex, titley, Plots.text(Base.getindex(sp, :title), title_font))
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:53 Plots.#plotly_annotation_dict#319("paper", "paper", #self#, x, y, ptxt)
│││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:53 Plots.KW(Plots.=>(:font, Plots.plotly_font(Base.getproperty(ptxt, :font))), Plots.=>(:xanchor, _8), Plots.=>(:yanchor, _9), Plots.=>(:rotation, Plots.-(Base.getproperty(Base.getproperty(ptxt, :font), :rotation))))
││││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
│││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Dict{Symbol, Any})
│││││││││││││││││││││└───────────────
│││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Dict{Symbol, Any})
│││││││││││││││││││││└───────────────
││││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
│││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Dict{Symbol, Any})
│││││││││││││││││││││└───────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1797 Plots.gr_display(plt)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:560 #self#(plt, "")
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:596 Plots.gr_display(sp, Plots.*(w, Plots.px), Plots.*(h, Plots.px), viewport_canvas)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:881 Plots.gr_draw_axes(sp, viewport_plotarea)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1207 Plots.gr_draw_axis_3d(sp, letter)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1238 Plots.axis_drawing_info_3d(sp, letter)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:753 Plots.!==(Plots.ind, Plots.nothing)
│││││││││││││││ variable Plots.ind is not defined: Plots.!==(Plots.ind, Plots.nothing)
││││││││││││││└───────────────────────────────────────────────────────────────
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:811 Plots.minorticks
│││││││││││││││ variable Plots.minorticks is not defined: Plots.minorticks
││││││││││││││└───────────────────────────────────────────────────────────────
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1249 Plots.gr_label_ticks_3d(sp, letter, Base.getproperty(ax, :ticks))
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1353 Plots.-(1, i)
│││││││││││││││ for one of the union split cases, no matching method found for signature: Plots.-(1, i::Union{Nothing, Int64})
││││││││││││││└───────────────────────────────────────────────────────────────────────
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:891 Plots.gr_add_series(sp, series)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1543 Plots.gr_draw_heatmap(series, x, y, z, clims)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1737 Plots.gr_xy_axislims(Plots.sp)
││││││││││││││ variable Plots.sp is not defined: Plots.gr_xy_axislims(Plots.sp)
│││││││││││││└───────────────────────────────────────────────────────────────────────
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:896 Plots.gr_draw_colorbar(cbar, sp, Plots.get_clims(sp), viewport_plotarea)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:491 Base.broadcasted(Plots.contour_levels, series, Plots.Ref(clims))
│││││││││││││┌ @ broadcast.jl:1263 Base.Broadcast.broadcasted(Core.tuple(Base.Broadcast.combine_styles(Core.tuple(arg1′, arg2′), args′...), f, arg1′, arg2′), args′...)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/FillArrays/RM6r2/src/fillbroadcast.jl:139 op(FillArrays.getindex_value(r), Base.getindex(x))
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:504 Core.kwfunc(Plots.range)(Core.apply_type(Core.NamedTuple, (:stop, :length))(Core.tuple(zmax, Plots.+(levels, 2))), Plots.range, zmin)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/utilities.jl:229 Colors.#range#7(stop, length, _3, start)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/utilities.jl:229 Core.kwfunc(Colors.range)(Core.apply_type(Core.NamedTuple, (:stop, :length))(Core.tuple(0.0, length)), Colors.range, 1.0)
││││││││││││││││││┌ @ range.jl:91 Base.#range#51(length, stop, step, _3, start)
│││││││││││││││││││┌ @ range.jl:91 Base._range(start, step, stop, length)
││││││││││││││││││││┌ @ twiceprecision.jl:609 Base._linspace(_, start_n, stop_n, len, den)
│││││││││││││││││││││┌ @ twiceprecision.jl:671 Base.steprangelen_hp(_, ref, step_full, Base.nbitslen(_, len, imin), Base.Int(len), imin)
││││││││││││││││││││││┌ @ twiceprecision.jl:323 Core.apply_type(Base.TwicePrecision, Base.Float64)(step, nb)
│││││││││││││││││││││││┌ @ twiceprecision.jl:185 Base.convert(_, hi)
││││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Float64}, hi::Tuple{Int128, Integer})
│││││││││││││││││││││││└─────────────────────────
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:502 Base.iterate(Plots.zip(Base.getindex(levels, Plots.:(1, Plots.-(Base.lastindex(levels), 1))), Base.getindex(levels, Plots.:(2, Base.lastindex(levels))), colors), Core.getfield(_10, 2))
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/sparse_int_set.jl:242 DataStructures.>(state, iterator_length)
││││││││││││││┌ @ operators.jl:303 Base.<(y, x)
│││││││││││││││┌ @ operators.jl:277 Base.isless(x, y)
││││││││││││││││ no matching method found for call signature: Base.isless(x::Int64, y::Tuple)
│││││││││││││││└────────────────────
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:525 Plots.plot_color(:black)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/colors.jl:8 PlotUtils.parse(Core.apply_type(PlotUtils.RGBA, PlotUtils.Float64), s)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/parse.jl:213 Colors.parse(_, Colors.string(desc))
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/parse.jl:209 Colors.convert(_, c)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/ColorTypes/RF8lb/src/conversions.jl:74 ColorTypes.cconvert(ColorTypes.ccolor(_, ColorTypes.typeof(c)), c)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/ColorTypes/RF8lb/src/conversions.jl:76 ColorTypes._convert(_, ColorTypes.base_color_type(_), ColorTypes.base_color_type(c), c)
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/ColorTypes/RF8lb/src/conversions.jl:100 ColorTypes.alpha(c)
│││││││││││││││││││ no matching method found for call signature: ColorTypes.alpha(c::Number)
││││││││││││││││││└───────────────────────────────────────────────────────────────────────────
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:905 Plots.gr_w3tondc(x, y, Plots.z)
││││││││││││ variable Plots.z is not defined: Plots.gr_w3tondc(x::Any, y::Any, Plots.z)
│││││││││││└──────────────────────────────────────────────────────────────────────
592.451942 seconds (1.14 G allocations: 68.468 GiB, 17.79% gc time)

[ Info profiling on density (second time)
═════ 30 possible errors found ═════
┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:402 Plots.#density#363(Core.tuple(Base.pairs(Core.NamedTuple()), #self#), args...)
│┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:402 Core.kwfunc(RecipesBase.plot)(Core.tuple(Base.merge(Base.merge(Base.NamedTuple(), kw), Core.apply_type(Core.NamedTuple, (:seriestype,))((:density,))), RecipesBase.plot), args...)
││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:51 Plots.#plot#129(Core.tuple(kw..., _3), args...)
│││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:55 Plots.Plot()
││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/types.jl:81 Plots.backend()
│││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:162 Plots._pick_default_backend()
││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:143 Plots.backend(sym)
│││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:184 Plots.backend(Plots._backend_instance(sym))
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends.jl:178 Base.setproperty!(Plots.CURRENT_BACKEND, :pkg, pkg)
│││││││││┌ @ Base.jl:34 Base.convert(Base.fieldtype(Base.typeof(x), f), v)
││││││││││ for one of the union split cases, no matching method found for signature: Base.convert(Base.fieldtype(Base.typeof(x::Plots.CurrentBackend)::Type{Plots.CurrentBackend}, f::Symbol)::Union{Type{Symbol}, Type{AbstractBackend}}, v::AbstractBackend)
│││││││││└──────────────
│││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:57 Plots._plot!(plt, plotattributes, args)
││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:167 RecipesPipeline.recipe_pipeline!(plt, plotattributes, args)
│││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/RecipesPipeline.jl:69 RecipesPipeline._process_userrecipes!(plt, plotattributes, args)
││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/user_recipe.jl:33 RecipesPipeline._finish_userrecipe!(plt, kw_list, next_series)
│││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/user_recipe.jl:99 RecipesPipeline.preprocess_attributes!(plt, kw)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/pipeline.jl:70 RecipesPipeline.preprocess_attributes!(plotattributes)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/args.jl:975 Plots.replaceAliases!(plotattributes, Plots._keyAliases)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:202 Plots.keys(plotattributes)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/container_loops.jl:233 DataStructures.SDMKeyIteration(ba)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/container_loops.jl:114 Core.apply_type(DataStructures.SDMKeyIteration, _)(base)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/container_loops.jl:114 Base.convert(_, base)
││││││││││││││┌ @ abstractdict.jl:518 _(x)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/sorted_dict.jl:119 Core.apply_type(DataStructures.SortedDict, _, _)(DataStructures.Forward, kv)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/sorted_dict.jl:124 DataStructures.not_iterator_of_pairs(kv)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/dict_support.jl:6 DataStructures.any(#61, Base.vect(DataStructures.iterate))
││││││││││││││││││┌ @ reducedim.jl:880 Base.#any#673(Base.:, #self#, f, a)
│││││││││││││││││││┌ @ reducedim.jl:880 Base._any(f, a, dims)
││││││││││││││││││││┌ @ reduce.jl:876 f(x)
│││││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/dict_support.jl:6 DataStructures.methodswith(DataStructures.typeof(Core.getfield(#self#, :kv)), x, true)
││││││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/InteractiveUtils/src/InteractiveUtils.jl:138 InteractiveUtils.#methodswith#62(false, #self#, t, f, meths)
│││││││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/InteractiveUtils/src/InteractiveUtils.jl:148 InteractiveUtils.push!(meths, d)
││││││││││││││││││││││││ no matching method found for call signature: InteractiveUtils.push!(meths::Bool, d::Method)
│││││││││││││││││││││││└────────────────────────────────────────────────────────────────────────────────────────────────────────
│││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/RecipesPipeline.jl:80 RecipesPipeline._process_plotrecipes!(plt, kw_list)
││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/plot_recipe.jl:16 RecipesPipeline._process_plotrecipe(plt, next_kw, kw_list, still_to_process)
│││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/plot_recipe.jl:31 RecipesBase.apply_recipe(kw, Core.apply_type(RecipesPipeline.Val, st), plt)
││││││││┌ @ /Users/aviatesk/.julia/packages/StatsPlots/6bINV/src/marginalhist.jl:9 Plots._hist_edges(Core.tuple(x, y), bns)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:718 Plots.map(#186, Core.tuple(Plots.:(1, _)...))
││││││││││┌ @ tuple.jl:180 f(Base.getindex(t, 1))
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:719 Plots._hist_edge(Core.getfield(#self#, :vs), dim, Base.getindex(Core.getfield(#self#, :binning), dim))
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:708 StatsBase.histrange(Base.getindex(vs, dim), binning, :left)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/StatsBase/ZxhK8/src/hist.jl:39 StatsBase.histrange(F(lo), F(hi), n, closed)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/StatsBase/ZxhK8/src/hist.jl:99 Base.floatrange(start, step, len, divisor)
│││││││││││││││┌ @ twiceprecision.jl:378 Base.floatrange(T, ia, ist, Base.Int(len), idivisor)
││││││││││││││││┌ @ twiceprecision.jl:361 Base.steprangelen_hp(_, Core.tuple(start_n, den), Core.tuple(step_n, den), 0, Base.Int(len), 1)
│││││││││││││││││┌ @ twiceprecision.jl:323 Core.apply_type(Base.TwicePrecision, Base.Float64)(step, nb)
││││││││││││││││││┌ @ twiceprecision.jl:185 Base.convert(_, hi)
│││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Float64}, hi::Tuple{Integer, Integer})
││││││││││││││││││└─────────────────────────
││││││││││││││││┌ @ twiceprecision.jl:368 Base.steprangelen_hp(_, Core.tuple(ref_n, den), Core.tuple(step_n, den), nb, Base.Int(len), imin)
│││││││││││││││││┌ @ twiceprecision.jl:323 Core.apply_type(Base.TwicePrecision, Base.Float64)(step, nb)
││││││││││││││││││┌ @ twiceprecision.jl:185 Base.convert(_, hi)
│││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Float64}, hi::Tuple{Integer, Integer})
││││││││││││││││││└─────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:953 Plots.xlims(Base.getindex(Base.getproperty(plt, :subplots), sp_index))
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:419 Plots.xlims(Plots.current(), sp_idx)
││││││││││ for one of the union split cases, no matching method found for signature: Plots.xlims(Plots.current()::Union{Nothing, AbstractPlot}, sp_idx::Int64)
│││││││││└────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:956 Plots.ylims(Base.getindex(Base.getproperty(plt, :subplots), sp_index))
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:420 Plots.ylims(Plots.current(), sp_idx)
││││││││││ for one of the union split cases, no matching method found for signature: Plots.ylims(Plots.current()::Union{Nothing, AbstractPlot}, sp_idx::Int64)
│││││││││└────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/recipes.jl:997 Plots.merge(plotattributes, Plots.copy(Base.getproperty(series, :plotattributes)))
│││││││││┌ @ abstractdict.jl:306 Base.merge!(Core.tuple(Base._typeddict(Core.tuple(d), others...)), others...)
││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/priorityqueue.jl:361 DataStructures.iterate(other, false)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/priorityqueue.jl:401 DataStructures.copy(Base.getproperty(pq, :index))
││││││││││││┌ @ dict.jl:120 Base.Dict(d)
│││││││││││││┌ @ dict.jl:129 Base.dict_with_eltype(#266, kv, Base.eltype(kv))
││││││││││││││┌ @ abstractdict.jl:530 DT_apply(_, _)(kv)
│││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Pkg/src/manifest.jl:139 Pkg.Types.get(info, "pinned", Pkg.Types.nothing)
││││││││││││││││ no matching method found for call signature: Pkg.Types.get(info::Int64, "pinned", Pkg.Types.nothing)
│││││││││││││││└───────────────────────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:319 RecipesBase.RecipeData(plotattributes, RecipesBase.wrap_tuple(args))
│││││││││┌ @ /Users/aviatesk/.julia/packages/RecipesBase/aQmWx/src/RecipesBase.jl:57 Base.convert(Core.fieldtype(RecipesBase.RecipeData, 1), plotattributes)
││││││││││┌ @ abstractdict.jl:518 _(x)
│││││││││││ no matching method found for call signature: _::Type{AbstractDict{Symbol, Any}}(x::Dict{_A, _B} where _B where _A)
││││││││││└───────────────────────
│││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/RecipesPipeline.jl:96 RecipesPipeline._process_seriesrecipes!(plt, kw_list)
││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/series_recipe.jl:25 RecipesPipeline._process_seriesrecipe(plt, series_attr)
│││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/series_recipe.jl:44 RecipesPipeline.add_series!(plt, plotattributes)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/pipeline.jl:314 Plots._add_the_series(plt, sp, plotattributes)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/pipeline.jl:371 Plots.warn_on_unsupported_args(Base.getproperty(plt, :backend), plotattributes)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/args.jl:1162 Base.iterate(Plots.keys(plotattributes))
│││││││││││┌ @ abstractdict.jl:60 Base.iterate(Core.tuple(Base.getproperty(v, :dict)), state...)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/RecipesPipeline/tkFmN/src/utils.jl:38 RecipesPipeline.collect(Base.getproperty(RecipesPipeline.Iterators, :flatten)(Core.tuple(exp_keys, def_keys)))
│││││││││││││┌ @ array.jl:624 Base._collect(Base.:(1, 1), itr, Base.IteratorEltype(itr), Base.IteratorSize(itr))
││││││││││││││┌ @ array.jl:635 Base.iterate(itr)
│││││││││││││││┌ @ iterators.jl:1089 #self#(f, ())
││││││││││││││││┌ @ iterators.jl:1097 Base.Iterators.iterate(Base.getproperty(f, :it), Base.getindex(x, 2))
│││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.Iterators.iterate(Base.getproperty(f::Base.Iterators.Flatten{Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}}, :it::Symbol)::Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Base.getindex(x::Union{Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Int64}, Tuple{Set{Symbol}, Int64}}, 2)::Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}})
││││││││││││││││└─────────────────────
││││││││││││││┌ @ array.jl:636 Base.iterate(itr, Core.getfield(_6, 2))
│││││││││││││││┌ @ iterators.jl:1093 Base.Iterators.iterate(Base.getproperty(f, :it), Base.getindex(state, 1))
││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.Iterators.iterate(Base.getproperty(f::Base.Iterators.Flatten{Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}}, :it::Symbol)::Tuple{Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Base.getindex(state::Tuple{Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}}, Int64}, 1)::Union{Int64, Base.KeySet{Symbol, Dict{Symbol, Any}}, Set{Symbol}})
│││││││││││││││└─────────────────────
││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:169 Plots._do_plot_show(plt, Base.getindex(plt, :show))
│││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:153 Plots.gui(plt)
││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:139 Plots.display(Plots.PlotsDisplay(), plt)
│││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:149 Plots.prepare_output(plt)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/plot.jl:186 Plots._update_min_padding!(sp)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:713 Plots.get_ticks(sp, xaxis)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:217 Plots.#get_ticks#110(true, #self#, sp, axis)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:241 Plots.optimal_ticks_and_labels(sp, axis)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:135 #self#(sp, axis, Plots.nothing)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:156 Core.kwfunc(Plots.optimize_datetime_ticks)(Core.apply_type(Core.NamedTuple, (:k_min, :k_max))(Core.tuple(2, 4)), Plots.optimize_datetime_ticks, Plots.*(8.64e7, amin), Plots.*(8.64e7, amax))
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:463 PlotUtils.#optimize_datetime_ticks#57(k_min, k_max, _3, a_min, a_max)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:463 PlotUtils.DateTime(Base.getproperty(PlotUtils.Dates, :UTM)(PlotUtils.Int64(PlotUtils.round(a_min))))
││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:383 #self#(y, 1, 1, 0, 0, 0, 0, Dates.TWENTYFOURHOUR)
│││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:383 Dates.Int64(y)
││││││││││││││││││ no matching method found for call signature: Dates.Int64(y::Dates.UTInstant)
│││││││││││││││││└──────────────────────────────────────────────────────────────────────────────────
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:496 PlotUtils.collect(PlotUtils.:(start, steplength, x_max))
││││││││││││││││┌ @ range.jl:991 Base.vcat(r)
│││││││││││││││││┌ @ range.jl:983 Base.iterate(ra)
││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/Dates/src/ranges.jl:59 Dates.length(r)
│││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/FixedPointNumbers/HAGk2/src/FixedPointNumbers.jl:251 Base.getproperty(r, :start)
││││││││││││││││││││┌ @ Base.jl:33 Base.getfield(x, f)
│││││││││││││││││││││ invalid builtin function call: Base.getfield(x::StepRange{Union{}, Union{}}, f::Symbol)
││││││││││││││││││││└──────────────
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:167 Core.kwfunc(Plots.optimize_ticks)(Core.apply_type(Core.NamedTuple, (:k_min, :k_max))(Core.tuple(4, 8)), Plots.optimize_ticks, sf(amin), sf(amax))
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:305 PlotUtils.#optimize_ticks#52(extend_ticks, k_min, k_max, scale, granularity_weight, simplicity_weight, coverage_weight, niceness_weight, strict_span, span_buffer, _3, x_min, x_max)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:305 Core.kwfunc(PlotUtils.optimize_ticks)(Core.apply_type(Core.NamedTuple, (:extend_ticks, :scale))(Core.tuple(extend_ticks, scale)), PlotUtils.optimize_ticks, PlotUtils.convert(PlotUtils.DateTime, x_min), PlotUtils.convert(PlotUtils.DateTime, x_max))
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:315 PlotUtils.#optimize_ticks#53(extend_ticks, k_min, k_max, scale, granularity_weight, simplicity_weight, coverage_weight, niceness_weight, strict_span, span_buffer, _3, x_min, x_max)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:408 Base.iterate(ticks, Core.getfield(_26, 2))
││││││││││││││││││┌ @ array.jl:785 Base.%(i, Base.UInt)
│││││││││││││││││││ no matching method found for call signature: Base.%(i::Tuple{Base.OneTo{Int64}, Int64}, Base.UInt)
││││││││││││││││││└────────────────
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/ticks.jl:408 Base.iterate(ticks, Core.getfield(_26, 2))
││││││││││││││││││┌ @ array.jl:785 Base.%(i, Base.UInt)
│││││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.%(i::Union{Int64, Tuple{Base.OneTo{Int64}, Int64}, Tuple{Int64, Nothing}}, Base.UInt)
││││││││││││││││││└────────────────
││││││││││││││││││┌ @ array.jl:785 Base.+(i, 1)
│││││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.+(i::Union{Int64, Tuple{Base.OneTo{Int64}, Int64}, Tuple{Int64, Nothing}}, 1)
││││││││││││││││││└────────────────
│││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/output.jl:150 Plots._display(plt)
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:949 Plots.standalone_html_window(plt)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:49 Plots.write_temp_html(plt)
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:36 Core.kwfunc(Plots.standalone_html)(Core.apply_type(Core.NamedTuple, (:title,))(Core.tuple(Base.getindex(Base.getproperty(plt, :attr), :window_title))), Plots.standalone_html, plt)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:7 Plots.#standalone_html#346(title, _3, plt)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/web.jl:7 Plots.html_body(plt)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:873 Plots.plotly_html_body(plt)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:903 #self#(plt, Plots.nothing)
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:908 Plots.plotly_series_json(plt)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:868 Plots.plotly_series(plt)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:862 Plots.plotly_series(plt, series)
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:507 Plots.plotly_series_shapes(plt, series, clims)
│││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:635 Plots.iter_segments(series)
││││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:88 Plots.push!(segs, seg)
│││││││││││││││││││││┌ @ array.jl:934 Base.convert(_, item)
││││││││││││││││││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:58 _(f)
│││││││││││││││││││││││ no matching method found for call signature: _::Type{UnitRange{Int64}}(f::LinearAlgebra.Factorization)
││││││││││││││││││││││└─────────────────────────────────────────────────────────────────────────────────────────────────
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:569 Plots.KW(Plots.=>(:show, true), Plots.=>(:color, Plots.rgba_string(Plots.plot_color(Base.getindex(series, :linecolor), Base.getindex(series, :linealpha)))), Plots.=>(:highlightwidth, Base.getindex(series, :linewidth)))
│││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
│││││││││││││││││││││ for one of the union split cases, no matching method found for signature: Base.convert(_::Type{Symbol}, key0::Union{Bool, String, Symbol})
││││││││││││││││││││└───────────────
│││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
│││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Bool)
││││││││││││││││││││└───────────────
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:616 Base.broadcasted(Plots.get_markercolor, series, inds)
│││││││││││││││││││┌ @ broadcast.jl:1260 Base.Broadcast.broadcastable(arg1)
││││││││││││││││││││┌ @ broadcast.jl:682 Base.Broadcast.collect(x)
│││││││││││││││││││││┌ @ array.jl:624 Base._collect(Base.:(1, 1), itr, Base.IteratorEltype(itr), Base.IteratorSize(itr))
││││││││││││││││││││││┌ @ array.jl:630 Base._similar_for(cont, Base.eltype(itr), itr, isz)
│││││││││││││││││││││││┌ @ array.jl:597 Base.length(itr)
││││││││││││││││││││││││ no matching method found for call signature: Base.length(itr::Plots.Series)
│││││││││││││││││││││││└────────────────
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:908 Plots.plotly_layout_json(plt)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:382 Plots.plotly_layout(plt)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:245 Plots.plotly_annotation_dict(titlex, titley, Plots.text(Base.getindex(sp, :title), title_font))
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:53 Plots.#plotly_annotation_dict#319("paper", "paper", #self#, x, y, ptxt)
│││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/plotly.jl:53 Plots.KW(Plots.=>(:font, Plots.plotly_font(Base.getproperty(ptxt, :font))), Plots.=>(:xanchor, _8), Plots.=>(:yanchor, _9), Plots.=>(:rotation, Plots.-(Base.getproperty(Base.getproperty(ptxt, :font), :rotation))))
││││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
│││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Dict{Symbol, Any})
│││││││││││││││││││││└───────────────
│││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Dict{Symbol, Any})
│││││││││││││││││││││└───────────────
││││││││││││││││││││┌ @ dict.jl:113 Base.setindex!(h, Base.getproperty(p, :second), Base.getproperty(p, :first))
│││││││││││││││││││││┌ @ dict.jl:374 Base.convert(_, key0)
││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Symbol}, key0::Dict{Symbol, Any})
│││││││││││││││││││││└───────────────
││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1797 Plots.gr_display(plt)
│││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:560 #self#(plt, "")
││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:596 Plots.gr_display(sp, Plots.*(w, Plots.px), Plots.*(h, Plots.px), viewport_canvas)
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:881 Plots.gr_draw_axes(sp, viewport_plotarea)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1207 Plots.gr_draw_axis_3d(sp, letter)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1238 Plots.axis_drawing_info_3d(sp, letter)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:753 Plots.!==(Plots.ind, Plots.nothing)
│││││││││││││││ variable Plots.ind is not defined: Plots.!==(Plots.ind, Plots.nothing)
││││││││││││││└───────────────────────────────────────────────────────────────
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/axes.jl:811 Plots.minorticks
│││││││││││││││ variable Plots.minorticks is not defined: Plots.minorticks
││││││││││││││└───────────────────────────────────────────────────────────────
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1249 Plots.gr_label_ticks_3d(sp, letter, Base.getproperty(ax, :ticks))
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1353 Plots.-(1, i)
│││││││││││││││ for one of the union split cases, no matching method found for signature: Plots.-(1, i::Union{Nothing, Int64})
││││││││││││││└───────────────────────────────────────────────────────────────────────
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:891 Plots.gr_add_series(sp, series)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1543 Plots.gr_draw_heatmap(series, x, y, z, clims)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:1737 Plots.gr_xy_axislims(Plots.sp)
││││││││││││││ variable Plots.sp is not defined: Plots.gr_xy_axislims(Plots.sp)
│││││││││││││└───────────────────────────────────────────────────────────────────────
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:896 Plots.gr_draw_colorbar(cbar, sp, Plots.get_clims(sp), viewport_plotarea)
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:491 Base.broadcasted(Plots.contour_levels, series, Plots.Ref(clims))
│││││││││││││┌ @ broadcast.jl:1263 Base.Broadcast.broadcasted(Core.tuple(Base.Broadcast.combine_styles(Core.tuple(arg1′, arg2′), args′...), f, arg1′, arg2′), args′...)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/FillArrays/RM6r2/src/fillbroadcast.jl:139 op(FillArrays.getindex_value(r), Base.getindex(x))
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/utils.jl:504 Core.kwfunc(Plots.range)(Core.apply_type(Core.NamedTuple, (:stop, :length))(Core.tuple(zmax, Plots.+(levels, 2))), Plots.range, zmin)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/utilities.jl:229 Colors.#range#7(stop, length, _3, start)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/utilities.jl:229 Core.kwfunc(Colors.range)(Core.apply_type(Core.NamedTuple, (:stop, :length))(Core.tuple(0.0, length)), Colors.range, 1.0)
││││││││││││││││││┌ @ range.jl:91 Base.#range#51(length, stop, step, _3, start)
│││││││││││││││││││┌ @ range.jl:91 Base._range(start, step, stop, length)
││││││││││││││││││││┌ @ twiceprecision.jl:609 Base._linspace(_, start_n, stop_n, len, den)
│││││││││││││││││││││┌ @ twiceprecision.jl:671 Base.steprangelen_hp(_, ref, step_full, Base.nbitslen(_, len, imin), Base.Int(len), imin)
││││││││││││││││││││││┌ @ twiceprecision.jl:323 Core.apply_type(Base.TwicePrecision, Base.Float64)(step, nb)
│││││││││││││││││││││││┌ @ twiceprecision.jl:185 Base.convert(_, hi)
││││││││││││││││││││││││ no matching method found for call signature: Base.convert(_::Type{Float64}, hi::Tuple{Int128, Integer})
│││││││││││││││││││││││└─────────────────────────
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:502 Base.iterate(Plots.zip(Base.getindex(levels, Plots.:(1, Plots.-(Base.lastindex(levels), 1))), Base.getindex(levels, Plots.:(2, Base.lastindex(levels))), colors), Core.getfield(_10, 2))
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/DataStructures/mgePl/src/sparse_int_set.jl:242 DataStructures.>(state, iterator_length)
││││││││││││││┌ @ operators.jl:303 Base.<(y, x)
│││││││││││││││┌ @ operators.jl:277 Base.isless(x, y)
││││││││││││││││ no matching method found for call signature: Base.isless(x::Int64, y::Tuple)
│││││││││││││││└────────────────────
││││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:525 Plots.plot_color(:black)
│││││││││││││┌ @ /Users/aviatesk/.julia/packages/PlotUtils/NS6Tf/src/colors.jl:8 PlotUtils.parse(Core.apply_type(PlotUtils.RGBA, PlotUtils.Float64), s)
││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/parse.jl:213 Colors.parse(_, Colors.string(desc))
│││││││││││││││┌ @ /Users/aviatesk/.julia/packages/Colors/kc2v8/src/parse.jl:209 Colors.convert(_, c)
││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/ColorTypes/RF8lb/src/conversions.jl:74 ColorTypes.cconvert(ColorTypes.ccolor(_, ColorTypes.typeof(c)), c)
│││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/ColorTypes/RF8lb/src/conversions.jl:76 ColorTypes._convert(_, ColorTypes.base_color_type(_), ColorTypes.base_color_type(c), c)
││││││││││││││││││┌ @ /Users/aviatesk/.julia/packages/ColorTypes/RF8lb/src/conversions.jl:100 ColorTypes.alpha(c)
│││││││││││││││││││ no matching method found for call signature: ColorTypes.alpha(c::Number)
││││││││││││││││││└───────────────────────────────────────────────────────────────────────────
│││││││││││┌ @ /Users/aviatesk/.julia/packages/Plots/fewot/src/backends/gr.jl:905 Plots.gr_w3tondc(x, y, Plots.z)
││││││││││││ variable Plots.z is not defined: Plots.gr_w3tondc(x::Any, y::Any, Plots.z)
│││││││││││└──────────────────────────────────────────────────────────────────────
696.384951 seconds (1.12 G allocations: 67.124 GiB, 16.06% gc time)

Using JET with GraphQL CodeGen! - Disable Checking with Comment?

I published tools for doing Julia CodeGen from GraphQL queries, and then using JET to type-check all the properties on the object that is received over the network! It's a really cool workflow, here's a video walkthrough and also here's a blog post

The only thing that would have been cool would be to like disable error reporting for a line? Like it was a potential error on someone else's library, would have been nice to just add a comment above like # jet-disable-next-line or something, that's popular in TypeScript.

Anyways, this package is awesome keep up the great work!!

abstract interpretation on toplevel frame

Currently JET uses JuliaInterpreter to interpret and concretize toplevel definitions (i.e. method/struct/macro definitions).
JET tries to select a subset of the statements in a lowered toplevel frame, which is necessary for JuliaInterpreter to interpret those toplevel definitions. LoweredCodeUtils.lines_required! takes the heavy burden of this, and it succeeds in selecting appropriate statements and other "toplevel call sites" are remained un-concretized (i.e. not-inteprreted):

@profile_toplevel begin
    foo(a) = a > 0 ? a : throw("foo") # concretized
    println(foo(-10)) # abstracted away
end
Output of `LoweredCodeUtils.print_with_code`
1 f 1 ─      $(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─     return $(Expr(:method, :foo))
)))
2 t │        $(Expr(:method, :foo))
3 t │   %3 = Core.Typeof(foo)
4 t │   %4 = Core.svec(%3, Core.Any)
5 t │   %5 = Core.svec()
6 t │   %6 = Core.svec(%4, %5, $(QuoteNode(:(#= untitled-dc2ff6168d2d868708725704d2d08de3:21 =#))))
7 t │        $(Expr(:method, :foo, :(%6), CodeInfo(
    @ untitled-dc2ff6168d2d868708725704d2d08de3:21 within `none'
1 ─ %1 = a > 0
└──      goto #3 if not %1
2 ─      return a
3 ─ %4 = throw("foo")
└──      return %4
)))
8 f └──      return foo

But it turns out this approach doesn't work well when the toplevel frame is more complex.
Especially, when a target file is a test file, there would be more complicated control flows, and LoweredCodeUtils.lines_required! ends up selecting too much statements:

@profile_toplevel begin
    using Test

    @testset begin
        foo(a) = a > 0 ? a : throw("foo") # concretized
        @inferred foo(-10) # concretized (thus leads to toplevel `ActualErrorWrapped` report)
    end
end
Output of `LoweredCodeUtils.print_with_code`
1 f 1 ──        Core.NewvarNode(:(_1))
2 f │           Core.NewvarNode(:(_2))
3 f │           Core.NewvarNode(:(_3))
4 f │           Core.NewvarNode(:(_4))
5 t │    %5   = Test.get_testset_depth()
6 t │    %6   = %5 == 0
7 t └───        goto #3 if not %6
8 t 2 ──        _12 = Test.DefaultTestSet
9 t └───        goto #4
10 t 3 ── %10  = Test.get_testset()
11 t └───        _12 = Test.typeof(%10)
12 f 4 ┄─ %12  = _12
13 f │           Test._check_testset(%12, $(QuoteNode(:(get_testset_depth() == 0))))
14 t │    %14  = Test.get_testset_depth()
15 t │    %15  = %14 == 0
16 t └───        goto #6 if not %15
17 t 5 ──        _13 = Test.DefaultTestSet
18 t └───        goto #7
19 t 6 ── %19  = Test.get_testset()
20 t └───        _13 = Test.typeof(%19)
21 t 7 ┄─ %21  = _13
22 t │    %22  = Base.NamedTuple()
23 t │    %23  = Core.apply_type(Test.Dict, Test.Symbol, Test.Any)
24 t │    %24  = (%23)()
25 t │    %25  = Base.merge(%22, %24)
26 t │    %26  = Base.isempty(%25)
27 t └───        goto #9 if not %26
28 t 8 ──        _14 = (%21)("test set")
29 t └───        goto #10
30 t 9 ── %30  = Core.kwfunc(%21)
31 t └───        _14 = (%30)(%25, %21, "test set")
32 f 10 ┄        _3 = _14
33 f │           Test.push_testset(_3)
34 t │           _2 = Test.default_rng()
35 t └───        _1 = Test.copy(_2)
36 t 11 ─        $(Expr(:enter, #36))
37 t 12 ─        _15 = -1
38 t 13 ─ %38  = $(Expr(:enter, #30))
39 f 14 ─ %39  = Base.getproperty(Test.Random, :seed!)
40 f │    %40  = Base.getproperty(_2, :seed)
41 f │           (%39)(%40)
42 t │           $(Expr(:thunk, CodeInfo(
  @ none within `top-level scope'
1 ─      global var"#foo#1"
│        const var"#foo#1"
│   %3 = Core._structtype(Main.##JETVirtualModule#321, Symbol("#foo#1"), Core.svec(), Core.svec(), false, 0)
│        var"#foo#1" = %3
│        Core._setsuper!(var"#foo#1", Core.Function)
│        Core._typebody!(var"#foo#1", Core.svec())
└──      return nothing
)))
43 t │    %43  = Core.svec(var"#foo#1", Core.Any)
44 t │    %44  = Core.svec()
45 t │    %45  = Core.svec(%43, %44, $(QuoteNode(:(#= untitled-dc2ff6168d2d868708725704d2d08de3:29 =#))))
46 t │           $(Expr(:method, false, :(%45), CodeInfo(
  @ untitled-dc2ff6168d2d868708725704d2d08de3:29 within `none'
1 ─ %1 = a > 0
└──      goto #3 if not %1
2 ─      return a
3 ─ %4 = throw("foo")
└──      return %4
)))
47 t │           _5 = %new(var"#foo#1")
48 f │           Core.NewvarNode(:(_6))
49 f │           Core.NewvarNode(:(_7))
50 f │           Core.NewvarNode(:(_8))
51 f │           Core.NewvarNode(:(_9))
52 t │           _10 = Core.apply_type(Union)
53 t │    %53  = _10 isa Test.Type
54 t └───        goto #16 if not %53
55 t 15 ─        goto #17
56 t 16 ─ %56  = Test.ArgumentError("@inferred requires a type as second argument")
57 t └───        Test.throw(%56)
58 t 17 ┄        _9 = Core.tuple(-10)
59 t │           _8 = Core._apply_iterate(Base.iterate, _5, _9)
60 t │    %60  = Base.getproperty(Test.Base, :return_types)
61 t │    %61  = _5
62 t │    %62  = Base.getproperty(Test.Base, :typesof)
63 t │    %63  = Core._apply_iterate(Base.iterate, %62, _9)
64 t │           _7 = (%60)(%61, %63)
65 t │    %65  = Test.length(_7)
66 t │    %66  = %65 == 1
67 t └───        goto #19 if not %66
68 t 18 ─        goto #20
69 t 19 ─ %69  = Base.AssertionError("length(inftypes) == 1")
70 t └───        Base.throw(%69)
71 t 20 ┄ %71  = _8 isa Test.Type
72 t └───        goto #22 if not %71
73 t 21 ─        _16 = Core.apply_type(Test.Type, _8)
74 t └───        goto #23
75 t 22 ─        _16 = Test.typeof(_8)
76 t 23 ┄        _6 = _16
77 t │    %77  = _6 <: _10
78 t └───        goto #25 if not %77
79 t 24 ─        goto #28
80 t 25 ─ %80  = _6
81 t │    %81  = Base.getindex(_7, 1)
82 t │    %82  = Test.typesplit(%81, _10)
83 t │    %83  = %80 == %82
84 t └───        goto #27 if not %83
85 t 26 ─        goto #28
86 t 27 ─ %86  = _6
87 t │    %87  = Base.getindex(_7, 1)
88 t │    %88  = Base.string("return type ", %86, " does not match inferred return type ", %87)
89 t └───        Test.error(%88)
90 f 28 ┄        _8
91 t └───        $(Expr(:leave, 1))
92 t 29 ─        goto #34
93 t 30 ┄        $(Expr(:leave, 1))
94 t 31 ─        _11 = $(Expr(:the_exception))
95 t │    %95  = _11 isa Test.InterruptException
96 t └───        goto #33 if not %95
97 f 32 ─        Test.rethrow()
98 t └───        goto #33
99 f 33 ┄ %99  = _3
100 f │    %100 = Test.Expr(:tuple)
101 f │    %101 = _11
102 f │    %102 = Base.getproperty(Test.Base, :catch_stack)
103 f │    %103 = (%102)()
104 f │    %104 = Test.Error(:nontest_error, %100, %101, %103, $(QuoteNode(:(#= untitled-dc2ff6168d2d868708725704d2d08de3:28 =#))))
105 f │           Test.record(%99, %104)
106 t └───        $(Expr(:pop_exception, :(%38)))
107 t 34 ┄        $(Expr(:leave, 1))
108 t 35 ─        goto #38
109 t 36 ┄        $(Expr(:leave, 1))
110 t 37 ─        _15 = 1
111 f 38 ┄        Test.copy!(_2, _1)
112 f │           Test.pop_testset()
113 f │           _4 = Test.finish(_3)
114 t │    %114 = _15 === 1
115 t └───        goto #40 if not %114
116 t 39 ─        Base.rethrow()
117 f 40 ┄ %117 = _4
118 f └───        return %117

We can implement our own version of LoweredCodeUtils.lines_required, and make the selection logic more appropriate for abstract interpretation,
but I think the right way to go would be to use the Julia's compiler abstract interpretation framework for toplevel code as well (, which is already done within JET to some extent).
Although Julia's native compiler doesn't interpret toplevel frame, and so it would need certain amount of work, there would also be possibilities to fix several issues around concrete-vs.-abstract story described below:

if rand(Bool)
    foo(a::Integer) = a
else
    foo(a::AbstractString) = a
end

foo("10") # the report for this should be deterministic

We can still use JuliaInterpreter and LoweredCodeUtils though; we still need to concretize toplevel definitions anyway, just because the abstract interpretation needs it.

static checker for numerical instability

just posting the idea here, I just realize one could check the potential numerical instability using an abstract interpreter, so instead of creating a new package, I feel it might fit better here, e.g

  1. a program is using the x>0 branch of exp, instead of converting it to exp(-x) form for x > 0 etc.
  2. 1/x and x can be a Julia expression that can potentially be zero

I guess there could be more cases for this type of error, but I didn't find any literature on this, I guess it's because instead of the Julia community, not many programming language folks focus on checking numerical programs?

Error with nested map

The following code

map(x->x, map(x->x, []) )

result in this error

TypeError: in new, expected UnionAll, got Type{Tuple}

I didn't manage to make it smaller, I have no clue on what's going on.

correctly handle cycles

7045d02 stopped to traverse frame chain on report construction, and rather update reports each time we go back to parent frames.

Currently JET doesn't handle cycles (mutual recursive frames) correctly, and as a result its virtual stack trace can be wrong.
It's easily confirmed by running the following snippets:

@eval Base begin # trigger a bug in a complex calls
    function show_sym(io::IO, sym::Symbol; allow_macroname=false)
        if is_valid_identifier(sym)
            print(io, sym)
        elseif allow_macroname && (sym_str = string(sym); startswith(sym_str, '@'))
            print(io, '@')
            show_sym(io, sym_str[2:end]) # NOTE: `sym_str[2:end]` here is errorneous
        else
            print(io, "var", repr(string(sym)))
        end
    end
end

@report_call println(QuoteNode(nothing))
...
┌ @ coreio.jl:4 Base.println(Core.tuple(Core.typeassert(Base.stdout, Base.IO)), xs...)
│┌ @ strings/io.jl:73 Base.print(Core.tuple(io), xs, Core.tuple("\n")...)
││┌ @ strings/io.jl:46 Base.print(io, x)
│││┌ @ show.jl:1209 Base.show_unquoted(Base.IOContext(io, Base.=>(:unquote_fallback, false)), ex, 0, -1)
││││┌ @ show.jl:1561 Base.show_unquoted_quote_expr(io, Base.getproperty(ex, :value), indent, prec, 0)
│││││┌ @ show.jl:1587 Base.show_block(Base.IOContext(io, Base.=>(Base.beginsym, false)), "quote", value, indent, quote_level)
││││││┌ @ show.jl:1430 Base.show_block(io, head, Base.vect(), block, i, quote_level)
│││││││┌ @ show.jl:1647 Base.show_unquoted(io, ex, 0, 0, quote_level)
││││││││┌ @ show.jl:2042 Core.kwfunc(Base.show_sym)(Core.apply_type(Core.NamedTuple, (:allow_macroname,))(Core.tuple(true)), Base.show_sym, io, mname)
│││││││││┌ @ REPL[4]:3 Base.#show_sym#921(allow_macroname, _3, io, sym)
││││││││││┌ @ REPL[4]:7 Base.show_sym(io, Base.getindex(sym_str, Base.:(2, Base.lastindex(sym_str))))
│││││││││││ no matching method found for call signature: Base.show_sym(io::IOContext, Base.getindex(sym_str::String, Base.:(2, Base.lastindex(sym_str::String)::Int64)::UnitRange{Int64})::String)
││││││││││└─────────────
...

and especially there is a missing frame between show.jl:1430 Base.show_block(io, head, Base.vect(), block, i, quote_level) and show.jl:1647 Base.show_unquoted(io, ex, 0, 0, quote_level) (i.e. show_block(io::IO, head, args::Vector, body, indent::Int, quote_level::Int)).
We can also confirm some the basic assertions like this don't hold in these cases.

One-line code fails type checking when using Base.split()

The one-line code

split("1,2,3", ',')

when saved to a file, fails type checking:

julia> using JET

julia> report_file("oneline.jl")
[toplevel-info] virtualized the context of Main (took 0.035 sec)
[toplevel-info] entered into oneline.jl
[toplevel-info]  exited from oneline.jl (took 2.966 sec)
═════ 2 possible errors found ═════
┌ @ oneline.jl:1 split("1,2,3", ',')
│┌ @ strings/util.jl:411 Base.#split#375(0, true, #self#, str, splitter)
││┌ @ strings/util.jl:411 Base._split(str, Base.isequal(splitter), limit, keepempty, _7)
│││┌ @ strings/util.jl:421 Base.first(r)
││││┌ @ abstractarray.jl:386 Base.iterate(itr)
│││││ no matching method found for call signature: Base.iterate(itr::Nothing)
││││└────────────────────────
│││┌ @ strings/util.jl:421 Base.last(r)
││││┌ @ abstractarray.jl:437 Base.lastindex(a)
│││││ no matching method found for call signature: Base.lastindex(a::Nothing)
││││└────────────────────────
(included_files = Set(["oneline.jl"]), any_reported = true)

Static array shape checking

Hi, this is probably outside the scope of your intended work, so feel free to close, but do you have any thoughts or plans for array shape checking?

I guess doing something like dex and remora would require extensions to Julia's type system?

FluxML/Flux.jl#614

https://github.com/google-research/dex-lang

https://arxiv.org/abs/1912.13451#:~:text=Remora%20is%20a%20higher%2Dorder,be%20executed%20on%20parallel%20hardware.

On the other hand, there are static analysis approaches like : https://github.com/google-research/swift-tfp

Errors on function definition using a global variable

I'm a Julia noob coming from the statically checked TypeScript world, so don't assume competence here.

I have this code in main.jl:

Circle = @NamedTuple begin
    radius::Float64
end

function area(c::Circle)
    pi * c.radius^2
end

area(Circle(2))

When I report_and_watch_file("main.jl"; annotate_types = true) I get

[toplevel-info] entered into src/main.jl
[toplevel-info]  exited from src/main.jl (took 0.008 sec)
═════ 1 toplevel error found ═════
┌ @ src/main.jl:31 
│ ArgumentError: invalid type for argument c in method definition for area at src/main.jl:31
└──────────────────

false positive error from a type constructor with parameterized vector field

I am not sure how to specify the concretization pattern for this code:

const MyType = AbstractVector{<:AbstractString}

struct Foo
    x::MyType
end

I tried using: report_file("main.jl"; analyze_from_definitions = true, concretization_patterns = [:(MyType = x_)])
but that results in this error:

┌ @ main.jl:4 Base.convert(Core.fieldtype(Foo, 1), x)
│┌ @ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:58 _(f)
││ no matching method found for call signature: _::Type{AbstractVector{var"#s20"} where var"#s20"<:AbstractString}(f::LinearAlgebra.Factorization)
│└───────────────────────────────────────────────────────────────────────────────────────────────────────────────

I am not sure how LinearAlgebra has entered the picture. Any advice on what the concretization pattern should be here? I am using JET v0.1.0 and Julia 1.6.0.

cached reports can get crazy when constant propagation happens

function foo(a)
    a < 0 ? "minus" : a
end

function bar(a)
    return a + foo(a)
end

interp, frame = profile_call(()->bar(10)) # => no report
interp, frame = profile_call(()->bar(-1)) # => get report
interp, frame = profile_call(()->bar(10)) # => get report ...

strange error during abstract interpretation

MRE:

julia> report_file(JET.fullbasepath("math.jl");
                   context = Base,                  # `Base.Math`'s root module
                   analyze_from_definitions = true, # there're only definitions in `Base`
                   )
[toplevel-info] virtualized the context of Base (took 0.042 sec)
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/math.jl
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/special/cbrt.jl
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/special/cbrt.jl (took 0.188 sec)
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/special/exp.jl
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/special/exp.jl (took 0.387 sec)
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/special/hyperbolic.jl
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/special/hyperbolic.jl (took 0.036 sec)
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/special/trig.jl
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/special/trig.jl (took 0.978 sec)
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/special/rem_pio2.jl
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/special/rem_pio2.jl (took 0.178 sec)
[toplevel-info] entered into /Users/aviatesk/julia/julia/base/special/log.jl
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/special/log.jl (took 0.065 sec)
[toplevel-info]  exited from /Users/aviatesk/julia/julia/base/math.jl (took 13.311 sec)
[toplevel-info] analyzing from top-level definitions ... 295/353ERROR: AssertionError: invalid lattice item
Stacktrace:
  [1] ⊑(a::Any, b::Any)
    @ Core.Compiler ./compiler/typelattice.jl:162
  [2] tmerge(typea::Any, typeb::Any)
    @ Core.Compiler ./compiler/typelimits.jl:291
  [3] getfield_tfunc(s00::Any, name::Any)
    @ Core.Compiler ./compiler/tfuncs.jl:856
  [4] builtin_tfunction(interp::Core.Compiler.AbstractInterpreter, f::Any, argtypes::Vector{Any}, sv::Union{Nothing, Core.Compiler.InferenceState})
    @ Core.Compiler ./compiler/tfuncs.jl:1520
  [5] builtin_tfunction(interp::JET.JETInterpreter, f::Any, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ JET ~/julia/packages/JET/src/tfuncs.jl:5

`NoMethodErrorReport` can have fairly lots of false positives for union-matching methods (because `abstract_call_gf_by_type` doesn't `abstract_call` matching methods using constant propagation)

MRE:

julia> foo(p, v) = setproperty!(p, :i, v)
foo (generic function with 1 method)

julia> mutable struct P
           s::String
           i::Int
       end

julia> @profile_call foo(P("s", 1), 2)
═════ 1 possible error found ═════
┌ @ none:1 Main.setproperty!(p::P, :i::Symbol, v::Int64)
│┌ @ Base.jl:34 Base.convert(Base.fieldtype(Base.typeof(x::P)::Type{P}, f::Symbol)::Union{Type{Int64}, Type{String}}, v::Int64)
││ for one of the union split cases, no matching method found for signature: Base.convert(Base.fieldtype(Base.typeof(x::P)::Type{P}, f::Symbol)::Union{Type{Int64}, Type{String}}, v::Int64)
│└──────────────
Int64

This is because abstract_call_gf_by_type first finds matching methods and does abstract calls using "non-constant" types (i.e. atype), and then does some constant propagation afterwards. TypeProfiler currently looks for the method matching table for collecting NoMethodErrorReport and so it never respects what can be obtained by constant propagation.

Well constant-propagation isn't done in error-safe way (it just eagerly propagate what inference succeeds to infer its type), so we can't just throw away NoMethodErrorReport if constant propagation succeeds.

toplevel function definitions with references to virtual global variables should be invalidated on their redefinition

mre:

foo(::Integer) = "good call, pal"
bar() = a

a = '1'
foo(bar()) # no method error should be reported

a = 1
foo(bar()) # no method error should NOT be reported
julia> profile_file("foo.jl")
═════ 2 possible errors found ═════
┌ @ foo.jl:5 foo(bar()::Char)
│ no matching method found for call signature: foo(bar()::Char)
└────────────
┌ @ foo.jl:8 foo(bar()::Char)
│ no matching method found for call signature: foo(bar()::Char)
└────────────
(Set(["foo.jl"]), true)

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Framework for pluggable analysis?

I wonder if it's possible to provide type checking as just one of many analyses that could be used with the JET framework. For example, performance analysis, numerical stability, taint analysis. It could be a pluggable framework.

virtualprocess.jl is problematic, find an alternative way to simulate toplevel execution

Top-level execution of profiled code is simulated by virtualprocess.jl, but currently it is highly problematic when considering support for full language features.
The current approach just relies on the analysis on surface-level AST, and so has tons of edges cases, e.g.:

varible scoping

begin
    local l
    l, g = sincos(1) # `g` should be global annotated while `l` keeps to be local
end

usage of global variables in toplevel definition

const MyInt = Int
struct T
    i::MyInt # <= `MyInt` can't be used here, since all the global assignments are done on virtually
end

I guess the alternative implementation should work on the lowered AST instead of surface AST, and here're the ideas:

  1. create top-level MethodInstance and run type inference on it
  • this allows us to reuse the existing abstract interpretation logic for toplevel code as well (consider a merge of control flow, etc.)
    • well, I'm really not sure it's a "valid" way to use MethodInstance; it seems that toplevel MethodInstance is only used for @generated functions
  • but now we need to find a way to directly evaluate toplevel definitions during abstract interpretation, which would complexify TypeProfiler.jl's injections into native abstract interpretation code
  1. use JuliaInterpreter.jl
  • with JuliaInterpreter.jl we can work on lowered AST, and we can even inject our code into the interpretatin process, so we can do
    • if the current statement is involved with a toplevel definitions, just evaluate it
    • if not, run abstract interpretation on it
  • but now we need to implement our own logic of abstract interpretation for top level frames, which may lead to duplicated, huge amount of work

analysis performance problem

Currently, JET can't finish analysis for "complex" calls in feasible time; e.g. a self-analysis below doesn't terminate in 1 hour ...

julia> using JET

julia> @time @report_call identity(nothing) # warm up analysis
No errors !
  3.447471 seconds (7.33 M allocations: 407.156 MiB, 7.20% gc time, 99.99% compilation time)
Core.Const(nothing)

julia> @time @report_call rand(Bool) # a bit complex analysis
No errors !
  4.491188 seconds (7.64 M allocations: 457.596 MiB, 2.49% gc time, 88.27% compilation time)
Bool

julia> @time report_call(JET.virtual_process!, (String, String, Module, Symbol, JET.JETInterpreter, JET.VirtualProcessResult)) # never terminates ...

There are two possibilities:

  • this is just a performance problem within JET.jl, which I guess is caused by our report construction/caching
  • or JET.jl has very bad inference customization and it causes infinite inference loops

analysis from method signatures (and even from a module definition)

Something like what ruby/typeprof does. We can integrate it with virtual_process! and using signatures of methods that are concretized by ConcreteInterpreter.

We should make sure abstract argument signatures doesn't produce additional reports, i.e. we only want to get true reports, and so e.g. Any argument shouldn't lead to "sound, but useless in practice" analysis.

benchmark tools for JET analysis

we want to:

  • setup a proper benchmark
  • ideally hook benchmarks with CI and show improvements/regressions on each PR/commit

As far as I understand we can't just reuse existing benchmarking tools; our main interest is in the first-time analysis performance and not in the cached analysis (, which BenchmarkTools.@btime measures, for example).
A simple script using @time or its family would be a good first step.

toplevel `ccall` causes an type assertion error

julia> report_text("""
       @ccall strlen("foo"::Cstring)::Csize_t
       """; toplevel_logger = IOContext(stdout, JET.LOGGER_LEVEL_KEY => 1),)
[toplevel-debug] analysis entered into top-level
[toplevel-debug] analyzing #= top-level:1 =#
[toplevel-debug] analyzing #= top-level:1 =# @ccall strlen("foo"::Cstring)::Csize_t
[toplevel-debug] analyzing begin
    local var"#162#arg1root" = Base.cconvert(Cstring, "foo")
    local var"#163#arg1" = Base.unsafe_convert(Cstring, var"#162#arg1root")
    $(Expr(:foreigncall, :(:strlen), :Csize_t, :(Core.svec(Cstring)), 0, :(:ccall), Symbol("#163#arg1"), Symbol("#162#arg1root")))
end
[toplevel-debug] concretization plan:
1 f 1 ─      _2 = Base.cconvert(Cstring, "foo")
2 f │        _1 = Base.unsafe_convert(Cstring, _2)
3 f │   %3 = $(Expr(:foreigncall, :(:strlen), :Csize_t, :(Core.svec(Cstring)), 0, :(:ccall), :(_1), :(_2)))
4 f └──      return %3
ERROR: TypeError: in typeassert, expected Core.SimpleVector, got a value of type Expr
Stacktrace:
  [1] getfield_elim_pass!(ir::Core.Compiler.IRCode)
    @ Core.Compiler ./compiler/ssair/passes.jl:567
  [2] run_passes(ci::Core.CodeInfo, nargs::Int64, sv::Core.Compiler.OptimizationState)
    @ Core.Compiler ./compiler/ssair/driver.jl:133
  [3] optimize
    @ ./compiler/optimize.jl:291 [inlined]
  [4] optimize
    @ ~/julia/packages/JET/src/optimize.jl:12 [inlined]
  [5] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:255
  [6] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/julia/packages/JET/src/typeinfer.jl:96
  [7] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:209
  [8] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/julia/packages/JET/src/typeinfer.jl:30
  [9] analyze_frame!(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/julia/packages/JET/src/JET.jl:623
 [10] analyze_toplevel!(interp::JET.JETInterpreter, src::Core.CodeInfo)
    @ JET ~/julia/packages/JET/src/JET.jl:525
 [11] virtual_process!(toplevelex::Expr, filename::String, virtualmod::Module, actualmodsym::Symbol, interp::JET.JETInterpreter, res::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}}})
    @ JET ~/julia/packages/JET/src/virtualprocess.jl:215
 [12] virtual_process!(s::String, filename::String, virtualmod::Module, actualmodsym::Symbol, interp::JET.JETInterpreter, res::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}}})
    @ JET ~/julia/packages/JET/src/virtualprocess.jl:78
 [13] virtual_process!
    @ ~/julia/packages/JET/src/virtualprocess.jl:62 [inlined]
 [14] #collect_reports#89
    @ ~/julia/packages/JET/src/JET.jl:482 [inlined]
 [15] report_text(io::Base.TTY, text::String, filename::String, mod::Module; jetconfigs::Base.Pairs{Symbol, IOContext{Base.TTY}, Tuple{Symbol}, NamedTuple{(:toplevel_logger,), Tuple{IOContext{Base.TTY}}}})
    @ JET ~/julia/packages/JET/src/JET.jl:470
 [16] report_text(args::String; jetconfigs::Base.Pairs{Symbol, IOContext{Base.TTY}, Tuple{Symbol}, NamedTuple{(:toplevel_logger,), Tuple{IOContext{Base.TTY}}}})
    @ JET ~/julia/packages/JET/src/JET.jl:476
 [17] top-level scope
    @ REPL[4]:1

In local inference, it works as expected:

julia> report_call() do
           @ccall strlen("foo"::Cstring)::Csize_t
       end
No errors !
UInt64

profiling performance and correctness

In this issue we track the simple benchmarking result with the following script:

density.jl

@info "package loading"
@time using JET

using JET: typeof′, profile_call
using Base.Meta, StatsPlots

macro benchmark(ex, kwargs...)
    @assert isexpr(ex, :call) "function call expression should be given"
    f = first(ex.args)
    args = ex.args[2:end]

    return quote let
        println(stdout)
        argtypes = $(typeof′).(($(map(esc, args)...),))        
        @info "profiling for $($(QuoteNode(ex))) ..."
        @time interp, frame = $(profile_call)($(esc(f)), argtypes; $(map(esc, kwargs)...))
        @info "$(length(interp.reports)) errors reported for $($(QuoteNode(ex)))"
    end end
end

# warm up
@benchmark rand(1000)

# first time heavy profiling
@benchmark  density(rand(1000))

# second time heavy profiling
@benchmark  density(rand(1000))

And here are the results:

on f175a6e (with report throw-away on constant prop' enabled, analysis on native code cache enabled)

❯ julia-dev density.jl
[ Info: package loading
  0.365807 seconds (641.21 k allocations: 40.460 MiB, 2.39% gc time, 51.17% compilation time)

[ Info: profiling for rand(1000) ...
  8.171590 seconds (10.22 M allocations: 648.577 MiB, 1.94% gc time, 86.54% compilation time)
[ Info: 0 errors reported for rand(1000)

[ Info: profiling for density(rand(1000)) ...
 33.087100 seconds (86.97 M allocations: 5.830 GiB, 6.62% gc time, 4.29% compilation time)
[ Info: 0 errors reported for density(rand(1000))

[ Info: profiling for density(rand(1000)) ...
  6.579445 seconds (21.44 M allocations: 1.258 GiB, 8.38% gc time, 0.00% compilation time)
[ Info: 0 errors reported for density(rand(1000))

on df15cbc (with report throw-away on constant prop' disabled, analysis on native code cache disabled)

❯ julia-dev density.jl
[ Info: package loading
  0.388810 seconds (644.23 k allocations: 40.643 MiB, 47.60% compilation time)

[ Info: profiling for rand(1000) ...
  3.979672 seconds (2.00 M allocations: 111.502 MiB, 0.61% gc time, 99.76% compilation time)
[ Info: 0 errors reported for rand(1000)

[ Info: profiling for density(rand(1000)) ...
 21.136394 seconds (51.79 M allocations: 3.529 GiB, 5.97% gc time, 17.71% compilation time)
[ Info: 55 errors reported for density(rand(1000))

[ Info: profiling for density(rand(1000)) ...
  2.925778 seconds (11.18 M allocations: 684.998 MiB, 8.24% gc time, 0.00% compilation time)
[ Info: 47 errors reported for density(rand(1000))

add report pass from `abstract_iteration`

We can report something like "iterate(::NeverTerminate) never terminates"

julia> struct NeverTerminate
           val::Int
       end

julia> Base.iterate(nv::NeverTerminate, state = 0) = state>nv.val ? (state, state+1) : (state, state+1)

julia> report_call() do
           for a in NeverTerminate(100)
               println(a)
           end
       end
No errors !
Union{}

Real-world stress test

If you want a real-world test case, I got #104 from attempting to use JET on the PaddedViews.jl runtest.jl file. I comment out the ambiguity and doctest portions, and then with SnoopCompile I get this:

tim@diva:~/.julia/dev/PaddedViews$ juliam --project
┌ Warning: no Manifest.toml file found, static paths used
└ @ Revise ~/.julia/dev/Revise/src/packagedef.jl:1361
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.6.0-rc1 (2021-02-06)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

shell> cd test
/home/tim/.julia/dev/PaddedViews/test

julia> using SnoopCompile

julia> tinf = @snoopi_deep include("runtests.jl")
Test Summary: | Pass  Total
PaddedView    |   74     74
Test Summary: | Pass  Total
paddedviews   |   24     24
Test Summary:   | Pass  Total
sym_paddedviews |   31     31
Test Summary: | Pass  Total
showarg       |    1      1
Test Summary: | Pass  Total
similar       |   60     60
Test Summary:   | Pass  Total
nothing/missing |   38     38
InferenceTimingNode: 4.723019/6.625027 on InferenceFrameInfo for Core.Compiler.Timings.ROOT() with 265 direct children

julia> itrigs = inference_triggers(tinf);

julia> length(itrigs)   # how many inference failures were there while the test suite was run? This tries to exclude things that obviously come from the tests themselves (though I'm a little nervous about whether it's really accurate)
30

julia> mtrigs = accumulate_by_source(Method, itrigs)   # group them by Method
17-element Vector{SnoopCompile.TaggedTriggers{Method}}:
 merge(a::NamedTuple, itr) in Base at namedtuple.jl:277 (1 callees from 1 callers)
 show(io::IO, ::MIME{Symbol("text/plain")}, X::AbstractArray) in Base at arrayshow.jl:332 (1 callees from 1 callers)
 alignment(io::IO, X::AbstractVecOrMat{T} where T, rows::AbstractVector{T}, cols::AbstractVector{V}, cols_if_complete::Integer, cols_otherwise::Integer, sep::Integer) where {T, V} in Base at arrayshow.jl:60 (1 callees from 1 callers)
 var"#any#698"(dims, ::typeof(any), f::Function, a::AbstractArray) in Base at reducedim.jl:883 (1 callees from 1 callers)
 var"#printstyled#820"(bold::Bool, color::Union{Int64, Symbol}, ::typeof(printstyled), msg...) in Base at util.jl:107 (1 callees from 1 callers)
 print_matrix_row(io::IO, X::AbstractVecOrMat{T} where T, A::Vector{T} where T, i::Integer, cols::AbstractVector{T} where T, sep::AbstractString) in Base at arrayshow.jl:96 (1 callees from 1 callers)
 any(f::Function, a::AbstractArray; dims) in Base at reducedim.jl:883 (1 callees from 1 callers)
 sym_paddedviews_itr(fillvalue, itr) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:324 (1 callees from 1 callers)
 print(io::IO, x) in Base at strings/io.jl:32 (2 callees from 1 callers)
 OffsetArray(A::AbstractArray, inds...) in OffsetArrays at /home/tim/.julia/dev/OffsetArrays/src/OffsetArrays.jl:195 (2 callees from 2 callers)
 _print_matrix(io, X::AbstractVecOrMat{T} where T, pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA) in Base at arrayshow.jl:173 (2 callees from 1 callers)
 showarg(io::IO, A::PaddedView, toplevel) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:338 (2 callees from 1 callers)
 (::Base.var"#printstyled##kw")(::Any, ::typeof(printstyled), msg...) in Base at util.jl:107 (2 callees from 2 callers)
 collect_to!(dest::AbstractArray{T, N} where N, itr, offs, st) where T in Base at array.jl:719 (3 callees from 1 callers)
 paddedviews_itr(fillvalue, itr) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:241 (3 callees from 1 callers)
 collect(itr::Base.Generator) in Base at array.jl:672 (3 callees from 1 callers)
 vect(X...) in Base at array.jl:125 (3 callees from 1 callers)

julia> mtrigs = filter(mtrigs) do mtrig     # skip the ones that can probably big ignored (again, a bit scary---is my analysis correct?)
           !all(isignorable ∘ suggest, mtrig.itrigs)
       end
11-element Vector{SnoopCompile.TaggedTriggers{Method}}:
 merge(a::NamedTuple, itr) in Base at namedtuple.jl:277 (1 callees from 1 callers)
 var"#any#698"(dims, ::typeof(any), f::Function, a::AbstractArray) in Base at reducedim.jl:883 (1 callees from 1 callers)
 var"#printstyled#820"(bold::Bool, color::Union{Int64, Symbol}, ::typeof(printstyled), msg...) in Base at util.jl:107 (1 callees from 1 callers)
 sym_paddedviews_itr(fillvalue, itr) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:324 (1 callees from 1 callers)
 OffsetArray(A::AbstractArray, inds...) in OffsetArrays at /home/tim/.julia/dev/OffsetArrays/src/OffsetArrays.jl:195 (2 callees from 2 callers)
 _print_matrix(io, X::AbstractVecOrMat{T} where T, pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA) in Base at arrayshow.jl:173 (2 callees from 1 callers)
 (::Base.var"#printstyled##kw")(::Any, ::typeof(printstyled), msg...) in Base at util.jl:107 (2 callees from 2 callers)
 collect_to!(dest::AbstractArray{T, N} where N, itr, offs, st) where T in Base at array.jl:719 (3 callees from 1 callers)
 paddedviews_itr(fillvalue, itr) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:241 (3 callees from 1 callers)
 collect(itr::Base.Generator) in Base at array.jl:672 (3 callees from 1 callers)
 vect(X...) in Base at array.jl:125 (3 callees from 1 callers)

julia> for (i, mtrig) in enumerate(mtrigs)
           println(i, ": ", mtrig)
           display(suggest(mtrig.itrigs[1]))
           println()
       end
1: merge(a::NamedTuple, itr) in Base at namedtuple.jl:277 (1 callees from 1 callers)
./namedtuple.jl:291: partial type call, perhaps annotate merge(a::NamedTuple{(), Tuple{}}, itr::Dict{Symbol, Any}) at namedtuple.jl:291 with type MethodInstance for (NamedTuple{(), T} where T<:Tuple)(::Tuple{})
If a noninferrable argument is a type or function, Julia's specialization heuristics may be responsible.

2: var"#any#698"(dims, ::typeof(any), f::Function, a::AbstractArray) in Base at reducedim.jl:883 (1 callees from 1 callers)
./reducedim.jl:883: non-inferrable or unspecialized call, perhaps annotate any(f::Function, a::Vector{Any}; dims::Function) at reducedim.jl:883 with type MethodInstance for _any(::Test.var"#27#29", ::Vector{Any}, ::Colon)
If a noninferrable argument is a type or function, Julia's specialization heuristics may be responsible.

3: var"#printstyled#820"(bold::Bool, color::Union{Int64, Symbol}, ::typeof(printstyled), msg...) in Base at util.jl:107 (1 callees from 1 callers)
./util.jl:107: vararg caller and callee (uninferred) (options: ignore, homogenize the arguments, declare an umbrella type, or force-specialize the callee MethodInstance for (::Base.var"#printstyled##kw")(::NamedTuple{(:bold, :color), Tuple{Bool, Symbol}}, ::typeof(printstyled), ::Base.TTY, ::String, ::Vararg{String, N} where N) in the caller)

4: sym_paddedviews_itr(fillvalue, itr) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:324 (1 callees from 1 callers)
/home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:325: non-inferrable or unspecialized call with vararg callee, perhaps annotate sym_paddedviews_itr(fillvalue::Int64, itr::Vector{Matrix{Int64}}) at PaddedViews.jl:325 with type MethodInstance for outerinds(::Matrix{Int64}, ::Matrix{Int64})
If a noninferrable argument is a type or function, Julia's specialization heuristics may be responsible.

5: OffsetArray(A::AbstractArray, inds...) in OffsetArrays at /home/tim/.julia/dev/OffsetArrays/src/OffsetArrays.jl:195 (2 callees from 2 callers)
/home/tim/.julia/dev/OffsetArrays/src/OffsetArrays.jl:195: uninferred inlineable vararg caller (options: add relevant specialization, ignore)

6: _print_matrix(io, X::AbstractVecOrMat{T} where T, pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA) in Base at arrayshow.jl:173 (2 callees from 1 callers)
./arrayshow.jl:201: non-inferrable or unspecialized call, perhaps annotate _print_matrix(io::IOContext{IOBuffer}, X::AbstractVecOrMat{T} where T, pre::String, sep::String, post::String, hdots::String, vdots::String, ddots::String, hmod::Int64, vmod::Int64, rowsA::UnitRange{Int64}, colsA::UnitRange{Int64}) at arrayshow.jl:201 with type MethodInstance for alignment(::IOContext{IOBuffer}, ::PaddedView{Int64, 2, Tuple{UnitRange{Int64}, UnitRange{Int64}}, Matrix{Int64}}, ::UnitRange{Int64}, ::UnitRange{Int64}, ::Int64, ::Int64, ::Int64)
If a noninferrable argument is a type or function, Julia's specialization heuristics may be responsible.

7: (::Base.var"#printstyled##kw")(::Any, ::typeof(printstyled), msg...) in Base at util.jl:107 (2 callees from 2 callers)
./util.jl:107: vararg caller and callee (uninferred) (options: ignore, homogenize the arguments, declare an umbrella type, or force-specialize the callee MethodInstance for var"#printstyled#820"(::Bool, ::Symbol, ::typeof(printstyled), ::String, ::Vararg{String, N} where N) in the caller)

8: collect_to!(dest::AbstractArray{T, N} where N, itr, offs, st) where T in Base at array.jl:719 (3 callees from 1 callers)
./generator.jl:47: Unspecialized or unknown for MethodInstance for (::PaddedViews.var"#5#6"{Int64, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}})(::LinearAlgebra.Adjoint{Float64, Vector{Float64}}) consider `stacktrace(itrig)` or `ascend(itrig)` to investigate more deeply

9: paddedviews_itr(fillvalue, itr) in PaddedViews at /home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:241 (3 callees from 1 callers)
/home/tim/.julia/dev/PaddedViews/src/PaddedViews.jl:242: non-inferrable or unspecialized call with vararg callee, perhaps annotate paddedviews_itr(fillvalue::Int64, itr::Vector{AbstractMatrix{T} where T}) at PaddedViews.jl:242 with type MethodInstance for outerinds(::Matrix{Int64}, ::LinearAlgebra.Adjoint{Float64, Vector{Float64}}, ::Vararg{Any, N} where N)
If a noninferrable argument is a type or function, Julia's specialization heuristics may be responsible.

10: collect(itr::Base.Generator) in Base at array.jl:672 (3 callees from 1 callers)
./generator.jl:47: Unspecialized or unknown for MethodInstance for (::PaddedViews.var"#5#6"{Int64, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}})(::Matrix{Int64}) consider `stacktrace(itrig)` or `ascend(itrig)` to investigate more deeply

11: vect(X...) in Base at array.jl:125 (3 callees from 1 callers)
./array.jl:126: vararg caller and callee (uninferred) (options: ignore, homogenize the arguments, declare an umbrella type, or force-specialize the callee MethodInstance for promote_typeof(::Matrix{Int64}, ::LinearAlgebra.Adjoint{Float64, Vector{Float64}}) in the caller)

Once #104 is addressed, this is basically what I'd try next until one gets to the state where JET can run this same example. Even with everything I've added (e.g., the isignorable stuff), I think most of the remainder is unfixable in the context of this package itself (Base might be a different story). SnoopCompile is only going to be able to catch a subset of what JET can detect, and even then SNR is a bit of a problem. (Still, 11 out of an initial 264 potential issues is a nice reduction.)

I'm suggesting PaddedViews simply because it's a package that has already gotten "the treatment" with SnoopCompile so it would be especially rewarding if JET discovered additional improvements. Obviously, it would be good to compare on packages that do have fixable issues; your README demo has examples of things that SnoopCompile can't catch.

World age issue

julia> profile_text("""
       using Test

       @testset begin
           a = @inferred(ones(Int,ntuple(d->1,1)), ntuple(x->x+1,1))
       end
       """)
ERROR: AssertionError: isempty(data.exception_frames) && !(data.caller_will_catch_err)
Stacktrace:
  [1] handle_err(interp::JET.ConcreteInterpreter, frame::JuliaInterpreter.Frame, err::MethodError)
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:459
  [2] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JuliaInterpreter ~/.julia/packages/JuliaInterpreter/hFiJ2/src/interpret.jl:561
  [3] step_expr!(interp::JET.ConcreteInterpreter, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:374
  [4] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter ~/.julia/packages/JuliaInterpreter/hFiJ2/src/interpret.jl:587
  [5] selective_eval!(recurse::Any, frame::JuliaInterpreter.Frame, isrequired::Vector{Bool}, istoplevel::Bool)
    @ LoweredCodeUtils ~/.julia/dev/LoweredCodeUtils/src/codeedges.jl:794
  [6] selective_eval_fromstart!(recurse::Any, frame::JuliaInterpreter.Frame, isrequired::Vector{Bool}, istoplevel::Bool)
    @ LoweredCodeUtils ~/.julia/dev/LoweredCodeUtils/src/codeedges.jl:819
  [7] #invokelatest#2
    @ ./essentials.jl:707 [inlined]
  [8] invokelatest
    @ ./essentials.jl:706 [inlined]
  [9] partially_interpret!
    @ ~/.julia/dev/JET/src/virtualprocess.jl:282 [inlined]
 [10] virtual_process!(toplevelex::Expr, filename::String, virtualmod::Module, actualmodsym::Symbol, interp::JET.JETInterpreter, ret::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}}})
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:183
 [11] virtual_process!(s::String, filename::String, virtualmod::Module, actualmodsym::Symbol, interp::JET.JETInterpreter, ret::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}}})
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:74
 [12] virtual_process!
    @ ~/.julia/dev/JET/src/virtualprocess.jl:61 [inlined]
 [13] #collect_reports#105
    @ ~/.julia/dev/JET/src/JET.jl:472 [inlined]
 [14] collect_reports
    @ ~/.julia/dev/JET/src/JET.jl:469 [inlined]
 [15] #collect_reports#103
    @ ~/.julia/dev/JET/src/JET.jl:453 [inlined]
 [16] collect_reports
    @ ~/.julia/dev/JET/src/JET.jl:453 [inlined]
 [17] profile_text(io::Base.TTY, text::String, filename::String, mod::Module; profiling_logger::Nothing, jetconfigs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JET ~/.julia/dev/JET/src/JET.jl:443
 [18] profile_text
    @ ~/.julia/dev/JET/src/JET.jl:443 [inlined]
 [19] profile_text(args::String; jetconfigs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JET ~/.julia/dev/JET/src/JET.jl:451
 [20] profile_text(args::String)
    @ JET ~/.julia/dev/JET/src/JET.jl:451
 [21] top-level scope
    @ REPL[4]:1

caused by: MethodError: no method matching (::Main.##JETVirtualModule#276.var"#1#3")(::Int64)
The applicable method may be too new: running in world age 29654, while current world is 29656.
Closest candidates are:
  (::Main.##JETVirtualModule#276.var"#1#3")(::Any) at none:0 (method too new to be called from this world context.)
Stacktrace:
  [1] ntuple(f::Main.##JETVirtualModule#276.var"#1#3", n::Int64)
    @ Base ./ntuple.jl:19
  [2] evaluate_call_recurse!(interp::JET.ConcreteInterpreter, frame::JuliaInterpreter.Frame, call_expr::Expr; enter_generated::Bool)
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:420
  [3] evaluate_call_recurse!
    @ ~/.julia/dev/JET/src/virtualprocess.jl:407 [inlined]
  [4] eval_rhs(recurse::Any, frame::JuliaInterpreter.Frame, node::Expr)
    @ JuliaInterpreter ~/.julia/packages/JuliaInterpreter/hFiJ2/src/interpret.jl:394
  [5] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JuliaInterpreter ~/.julia/packages/JuliaInterpreter/hFiJ2/src/interpret.jl:532
  [6] step_expr!(interp::JET.ConcreteInterpreter, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:374
  [7] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter ~/.julia/packages/JuliaInterpreter/hFiJ2/src/interpret.jl:587
  [8] selective_eval!(recurse::Any, frame::JuliaInterpreter.Frame, isrequired::Vector{Bool}, istoplevel::Bool)
    @ LoweredCodeUtils ~/.julia/dev/LoweredCodeUtils/src/codeedges.jl:794
  [9] selective_eval_fromstart!(recurse::Any, frame::JuliaInterpreter.Frame, isrequired::Vector{Bool}, istoplevel::Bool)
    @ LoweredCodeUtils ~/.julia/dev/LoweredCodeUtils/src/codeedges.jl:819
 [10] #invokelatest#2
    @ ./essentials.jl:707 [inlined]
 [11] invokelatest
    @ ./essentials.jl:706 [inlined]
 [12] partially_interpret!
    @ ~/.julia/dev/JET/src/virtualprocess.jl:282 [inlined]
 [13] virtual_process!(toplevelex::Expr, filename::String, virtualmod::Module, actualmodsym::Symbol, interp::JET.JETInterpreter, ret::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}}})
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:183
 [14] virtual_process!(s::String, filename::String, virtualmod::Module, actualmodsym::Symbol, interp::JET.JETInterpreter, ret::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}}})
    @ JET ~/.julia/dev/JET/src/virtualprocess.jl:74
 [15] virtual_process!
    @ ~/.julia/dev/JET/src/virtualprocess.jl:61 [inlined]
 [16] #collect_reports#105
    @ ~/.julia/dev/JET/src/JET.jl:472 [inlined]
 [17] collect_reports
    @ ~/.julia/dev/JET/src/JET.jl:469 [inlined]
 [18] #collect_reports#103
    @ ~/.julia/dev/JET/src/JET.jl:453 [inlined]
 [19] collect_reports
    @ ~/.julia/dev/JET/src/JET.jl:453 [inlined]
 [20] profile_text(io::Base.TTY, text::String, filename::String, mod::Module; profiling_logger::Nothing, jetconfigs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JET ~/.julia/dev/JET/src/JET.jl:443
 [21] profile_text
    @ ~/.julia/dev/JET/src/JET.jl:443 [inlined]
 [22] profile_text(args::String; jetconfigs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JET ~/.julia/dev/JET/src/JET.jl:451
 [23] profile_text(args::String)
    @ JET ~/.julia/dev/JET/src/JET.jl:451
 [24] top-level scope
    @ REPL[4]:1

invalidate JET analysis cached with the different configurations

Each call below shouldn't produce different results.

julia> using JET

julia> @report_call aggressive_constant_propagation = true rand(Bool)
No errors !
Bool

julia> @report_call aggressive_constant_propagation = false rand(Bool)
No errors !
Bool
julia> using JET

julia> @report_call aggressive_constant_propagation = false rand(Bool)
═════ 2 possible errors found ═════
┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/Random.jl:259 Random.default_rng()
│┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:370 Random.default_rng(Base.getproperty(Random.Threads, :threadid)())
││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:376 Random.MersenneTwister()
│││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:147 #self#(Random.nothing)
││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:147 Random.seed!(Random.MersenneTwister(Core.apply_type(Random.Vector, Random.UInt32)(), Random.DSFMT_state()), seed)
│││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/Random.jl:426 Random.seed!(rng)
││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:362 Random.make_seed()
│││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:326 Random.pipeline(Base.cmd_gen(Core.tuple(Core.tuple("ifconfig"))), Base.cmd_gen(Core.tuple(Core.tuple("sha1sum"))))
││││││││┌ @ cmd.jl:331 Core.kwfunc(Base.pipeline)(Core.apply_type(Core.NamedTuple, (:stdout,))(Core.tuple(dest)), Base.pipeline, cmd)
│││││││││┌ @ cmd.jl:323 Base.redir_out(cmd, stdout)
││││││││││┌ @ cmd.jl:323 Base.redir_out_append(cmd, stdout)
│││││││││││ no matching method found for call signature: Base.redir_out_append(cmd::Cmd, stdout::Cmd)
││││││││││└──────────────
│││││││┌ @ parse.jl:241 Base.haskey(_2, :base)
││││││││┌ @ parse.jl:241 Base.#parse#439(base, _3, _4, s)
│││││││││┌ @ parse.jl:241 Base.convert(_, Base.tryparse_internal(_, s, Base.firstindex(s), Base.lastindex(s), _6, true))
││││││││││ for any of the union split cases, no matching method found for call signature: Base.convert(_::Type{UInt64}, Base.tryparse_internal(_::Type{UInt64}, s::String, Base.firstindex(s::String)::Int64, Base.lastindex(s::String)::Int64, _6::Int64, true)::Union{Nothing, UInt64})
│││││││││└────────────────
Bool

julia> @report_call aggressive_constant_propagation = true rand(Bool)
═════ 2 possible errors found ═════
┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/Random.jl:259 Random.default_rng()
│┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:370 Random.default_rng(Base.getproperty(Random.Threads, :threadid)())
││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:376 Random.MersenneTwister()
│││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:147 #self#(Random.nothing)
││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:147 Random.seed!(Random.MersenneTwister(Core.apply_type(Random.Vector, Random.UInt32)(), Random.DSFMT_state()), seed)
│││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/Random.jl:426 Random.seed!(rng)
││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:362 Random.make_seed()
│││││││┌ @ /Users/aviatesk/julia/julia/usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:326 Random.pipeline(Base.cmd_gen(Core.tuple(Core.tuple("ifconfig"))), Base.cmd_gen(Core.tuple(Core.tuple("sha1sum"))))
││││││││┌ @ cmd.jl:331 Core.kwfunc(Base.pipeline)(Core.apply_type(Core.NamedTuple, (:stdout,))(Core.tuple(dest)), Base.pipeline, cmd)
│││││││││┌ @ cmd.jl:323 Base.redir_out(cmd, stdout)
││││││││││┌ @ cmd.jl:323 Base.redir_out_append(cmd, stdout)
│││││││││││ no matching method found for call signature: Base.redir_out_append(cmd::Cmd, stdout::Cmd)
││││││││││└──────────────
│││││││┌ @ parse.jl:241 Base.haskey(_2, :base)
││││││││┌ @ parse.jl:241 Base.#parse#439(base, _3, _4, s)
│││││││││┌ @ parse.jl:241 Base.convert(_, Base.tryparse_internal(_, s, Base.firstindex(s), Base.lastindex(s), _6, true))
││││││││││ for any of the union split cases, no matching method found for call signature: Base.convert(_::Type{UInt64}, Base.tryparse_internal(_::Type{UInt64}, s::String, Base.firstindex(s::String)::Int64, Base.lastindex(s::String)::Int64, _6::Int64, true)::Union{Nothing, UInt64})
│││││││││└────────────────
Bool

What does "The applicable method may be too new" mean?

When I run JET on my project, it failed with the following. It doesn't point to anywhere in my codebase, so it's unclear what has gone wrong.

ERROR: MethodError: no method matching namemap(::Type{MathOptInterface.ActivationCondition})
The applicable method may be too new: running in world age 29620, while current world is 29981.
Closest candidates are:
  namemap(::Type{MathOptInterface.ActivationCondition}) at Enums.jl:195 (method too new to be called from this world context.)
  namemap(::Type{MathOptInterface.FileFormats.MPS.Sense}) at Enums.jl:195 (method too new to be called from this world context.)
  namemap(::Type{Pkg.Types.PreserveLevel}) at Enums.jl:195
  ...
Stacktrace:
  [1] Symbol(x::MathOptInterface.ActivationCondition)
    @ Base.Enums ./Enums.jl:26
  [2] show(io::IOContext{IOBuffer}, x::MathOptInterface.ActivationCondition)
    @ Base.Enums ./Enums.jl:31
  [3] sprint(f::Function, args::Type; context::IOBuffer, sizehint::Int64)
    @ Base ./strings/io.jl:103
  [4] print_type_stacktrace(io::IOBuffer, type::Type; color::Symbol)
    @ Base ./show.jl:2262
  [5] print_type_stacktrace(io::IOBuffer, type::Type)
    @ Base ./show.jl:2262
  [6] show_tuple_as_call(io::IOBuffer, name::Symbol, sig::Type, demangle::Bool, kwargs::Nothing, argnames::Nothing, qualified::Bool)
    @ Base ./show.jl:2243
  [7] sprint(::Function, ::Symbol, ::Vararg{Any, N} where N; context::Nothing, sizehint::Int64)
    @ Base ./strings/io.jl:105
  [8] sprint
    @ ./strings/io.jl:101 [inlined]
  [9] get_sig
    @ ~/.julia/packages/JET/4GIWe/src/reports.jl:325 [inlined]
 [10] get_virtual_frame(interp::JET.JETInterpreter, loc::Core.MethodInstance)
    @ JET ~/.julia/packages/JET/4GIWe/src/reports.jl:291
 [11] UncaughtExceptionReport
    @ ~/.julia/packages/JET/4GIWe/src/reports.jl:168 [inlined]
 [12] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:154
 [13] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:209
 [14] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:30
 [15] typeinf_edge(interp::JET.JETInterpreter, method::Method, atypes::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:806
 [16] abstract_call_method(interp::JET.JETInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:490
 [17] abstract_call_method
    @ ~/.julia/packages/JET/4GIWe/src/abstractinterpretation.jl:240 [inlined]
 [18] abstract_call_gf_by_type(interp::JET.JETInterpreter, f::Any, argtypes::Vector{Any}, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ~/.julia/packages/JET/4GIWe/src/legacy/abstractinterpretation:158
 [19] abstract_call_known(interp::JET.JETInterpreter, f::Any, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1033
 [20] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1056
 [21] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1040
 [22] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1167
 [23] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/abstractinterpretation.jl:416
 [24] typeinf_local(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1462
 [25] typeinf_nocycle(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1520
 [26] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:214
 [27] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:96
 [28] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:209
 [29] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:30
 [30] typeinf_edge(interp::JET.JETInterpreter, method::Method, atypes::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:806
 [31] abstract_call_method(interp::JET.JETInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:490
 [32] abstract_call_method
    @ ~/.julia/packages/JET/4GIWe/src/abstractinterpretation.jl:240 [inlined]
 [33] abstract_call_gf_by_type(interp::JET.JETInterpreter, f::Any, argtypes::Vector{Any}, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ~/.julia/packages/JET/4GIWe/src/legacy/abstractinterpretation:158
 [34] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1054
 [35] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1040
 [36] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1167
 [37] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/abstractinterpretation.jl:416
 [38] typeinf_local(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1462
 [39] typeinf_nocycle(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1520
 [40] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:214
 [41] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:96
 [42] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:209
 [43] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:30
 [44] typeinf_edge(interp::JET.JETInterpreter, method::Method, atypes::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:806
 [45] abstract_call_method(interp::JET.JETInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:490
 [46] abstract_call_method
    @ ~/.julia/packages/JET/4GIWe/src/abstractinterpretation.jl:240 [inlined]
 [47] abstract_call_gf_by_type(interp::JET.JETInterpreter, f::Any, argtypes::Vector{Any}, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ~/.julia/packages/JET/4GIWe/src/legacy/abstractinterpretation:158
 [48] abstract_call_known(interp::JET.JETInterpreter, f::Any, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1033
 [49] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1056
--- the last 15 lines are repeated 2 more times ---
 [80] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1040
 [81] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1167
 [82] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/abstractinterpretation.jl:416
 [83] typeinf_local(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1462
 [84] typeinf_nocycle(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/abstractinterpretation.jl:1520
 [85] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:214
 [86] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:96
 [87] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ Core.Compiler ./compiler/typeinfer.jl:209
 [88] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/typeinfer.jl:30
 [89] analyze_frame!(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
    @ JET ~/.julia/packages/JET/4GIWe/src/JET.jl:738
 [90] analyze_method_signature!(interp::JET.JETInterpreter, m::Method, atype::Any, sparams::Core.SimpleVector)
    @ JET ~/.julia/packages/JET/4GIWe/src/JET.jl:734
 [91] analyze_from_definitions!(interp::JET.JETInterpreter, res::NamedTuple{(:included_files, :toplevel_error_reports, :inference_error_reports, :toplevel_signatures, :actual2virtual), Tuple{Set{String}, Vector{JET.ToplevelErrorReport}, Vector{JET.InferenceErrorReport}, Vector{Type}, Pair{Module, Module}}})
    @ JET ~/.julia/packages/JET/4GIWe/src/virtualprocess.jl:234
 [92] virtual_process(x::String, filename::String, actualmod::Module, interp::JET.JETInterpreter, config::JET.ToplevelConfig, virtualmod::Module)
    @ JET ~/.julia/packages/JET/4GIWe/src/virtualprocess.jl:212
 [93] #analyze_text#103
    @ ~/.julia/packages/JET/4GIWe/src/JET.jl:618 [inlined]
 [94] analyze_file(filename::String, args::Module; jetconfigs::Base.Iterators.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:toplevel_logger, :analyze_from_definitions), Tuple{IOContext{Base.TTY}, Bool}}})
    @ JET ~/.julia/packages/JET/4GIWe/src/JET.jl:509
 [95] #report_file#96
    @ ~/.julia/packages/JET/4GIWe/src/JET.jl:493 [inlined]
 [96] report_file(args::String; jetconfigs::Base.Iterators.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:analyze_from_definitions,), Tuple{Bool}}})
    @ JET ~/.julia/packages/JET/4GIWe/src/JET.jl:496

AssertionError: invalid global caching

I wanted to try JET with CUDA.jl's vadd.jl example, but profile_file runs into:

julia> profile_file("examples/vadd.jl"; annotate_types = true)
ERROR: AssertionError: invalid global caching MethodInstance for GPUArrays.var"#gpu_call#1"(::AbstractArray, ::Union{Nothing, Int64}, ::Union{Nothing, Int64}, ::Union{Nothing, Int64}, ::Union{Nothing, String}, ::typeof(GPUArrays.gpu_call), ::F, ::Any, ::Vararg{Any, N}) where {F, N}
Stacktrace:
   [1] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ JET ~/Julia/pkg/JET/src/typeinfer.jl:161
   [2] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:209
   [3] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ JET ~/Julia/pkg/JET/src/typeinfer.jl:21
   [4] typeinf_edge
     @ ./compiler/typeinfer.jl:818 [inlined]
...

This is on latest 1.7 (today's nightly). Can look into reducing to something that doesn't require CUDA, if needed.

Report linting errors using Julia's `Logging` stdlib...

...or at least have the option to. The motivation here is that it is very easy to work with logging records, which makes it easier to create new printing/interaction methods. I'm particularly interested in generating GitHub annotations from JET.jl results. See here for an example of what annotations look like for test failures.

JET analysis will produce code different from what Julia's native compiler produces.

This is a little disturbing, but I'm able to reproduce it 100% reliably. In the two examples below, the exact same function f is shown to compile differently depending on whether JET is used or not:

MWE

using ErrorTypes # commit 59441d34530aa4fcd366885575847f3b15ca5902
# using JET # commit 37151f880ab067ac2ddd6d1e2338c3b8e14c4cdc
safediv(a, b)::Option{Float64} = iszero(b) ? none : some(a/b)
f(x)::Option{Float64} = some(@? safediv(1, x))
# @report_call f(1)
@code_native f(1)

Try running the above and look at the native code, and then run it again without the two lines commented out.

False positive:

An example where JET detects an possible MethodError, even if the branch containing the error is compiled away by the compiler.

MWE

using ErrorTypes
using JET

safediv(a, b)::Option{Float64} = iszero(b) ? none : some(a/b)
f(x)::Option{Float64} = some(@? safediv(1, x))

@report_call f(1)
@code_native f(1)

You can confirm in the native code that no error is possible, yet JET reports:

═════ 2 possible errors found ═════
┌ @ /Users/jakobnissen/.julia/packages/ErrorTypes/Z99Pb/src/ErrorTypes.jl:64 Base.convert(Core.apply_type(Main.Option, Main.Float64), ErrorTypes.Err(Base.getproperty(Base.getproperty(##262, :data), :_1)))
│ for one of the union split cases, no matching method found for signature: Base.convert(Core.apply_type(Main.Option, Main.Float64)::Type{Option{Float64}}, ErrorTypes.Err(Base.getproperty(Base.getproperty(##262::Option{Float64}, :data::Symbol)::Union{Err{Float64, Nothing}, Ok{Float64, Nothing}}, :_1::Symbol)::Union{Nothing, Float64})::Union{ErrorTypes.ResultConstructor{Err, Nothing}, ErrorTypes.ResultConstructor{Err, Float64}})
└────────────────────────────────────────────────────────────────────────────
┌ @ REPL[19]:1 Base.convert(Core.apply_type(Main.Option, Main.Float64), Main.some(_4))
│ for one of the union split cases, no matching method found for signature: Base.convert(Core.apply_type(Main.Option, Main.Float64)::Type{Option{Float64}}, Main.some(_4::Union{Nothing, Float64})::Union{Option{Float64}, Option{Nothing}})
└──────────────
Option{Float64} (alias for Result{Float64, Nothing})

Bizarrely, this error seems also to be @code_warntype, even if it is compiled effectively regardless.

`LoweredCodeUtils.lines_required!` selects too much statements in a `try/catch` block

The following test case should pass:

res = @analyze_toplevel try
    f(a) = throw(a)
    f(10)
catch err
    typeof(err)
end
@test isempty(res.toplevel_error_reports)
@test !isempty(res.inference_error_reports)

But currently LoweredCodeUtils.lines_required! selects all the statements within a try/catch block when there is an inner function within it:

julia> res = @analyze_toplevel toplevel_logger=IOContext(stdout, JET.LOGGER_LEVEL_KEY=>1) try
    f(a) = throw(a)
    f(10)
catch err
    typeof(err)
end

[toplevel-debug] concretization plan:
 1 t 1%1  = $(Expr(:enter, #4))
 2 t 2$(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─      global var"#f#1"
│        const var"#f#1"
│   %3 = Core._structtype(Main.##JETVirtualModule#288, Symbol("#f#1"), Core.svec(), Core.svec(), false, 0)
│        var"#f#1" = %3
│        Core._setsuper!(var"#f#1", Core.Function)
│        Core._typebody!(var"#f#1", Core.svec())
└──      return nothing
)))
 3 t │   %3  = Core.svec(var"#f#1", Core.Any)
 4 t │   %4  = Core.svec()
 5 t │   %5  = Core.svec(%3, %4, $(QuoteNode(:(#= untitled-2191002623ad8bd17558600d3282cb36:35 =#))))
 6 t │         $(Expr(:method, false, :(%5), CodeInfo(
    @ untitled-2191002623ad8bd17558600d3282cb36:35 within `none'
1 ─ %1 = throw(a)
└──      return %1
)))
 7 t │         _1 = %new(var"#f#1")
 8 t │   %8  = (_1)(10)
 9 t └──       $(Expr(:leave, 1))
10 t 3 ─       return %8
11 t 4 ┄       $(Expr(:leave, 1))
12 f 5 ─       _2 = $(Expr(:the_exception))
13 f │   %13 = typeof(_2)
14 f │         $(Expr(:pop_exception, :(%1)))
15 f └──       return %13

Especially, this part of LoweredCodeUtils.jl selects those statements by traversing control flows.
Respecting a control flow itself is necessary (e.g. consider @eval funcdef inside a loop), and so I guess we need a special configuration of norequire to escape statements within a try/catch here.

When returning tuples, the variables are incorrectly detected as not defined

shell> cat ~/test.jl
a, b = sincos(2)
c = b

julia> profile_file("/home/bla/test.jl"; annotate_types = true)
═════ 1 possible error found ═════
┌ @ /home/bla/test.jl:2 b
│ variable b is not defined: b
└────────────────────────────
(Set(["/home/bla/test.jl"]), true)

global variable woe

There're mainly two big problems around how JET treats global variabels

1. propagate of non-constant global variables

I thought we can safely propagate the type of (non constant) global variable if we invalidate all the code cache that uses it upon its update (the force_invalidate! logic), but it was wrong.
This is just because we can't invalidate code cache if the update happens within the lineage frames of the current frame. Consider the following example:

var = '1'

function foo(v)
    rand(Bool) && setter!(v)
    sin(var) # <= var::Union{Char,Int} ?
end
setter!(v) = global var = v

foo(10)

Now we need to annotate var as Union{Char,Int}, but this annotation is actually very hard (or even impossible, with the existence of the widening heuristics) to be done in general case (while this particular example is very simple, setter! can happen in a deeply nested conditioned callee).

I guess this is why Julia's native compiler doesn't do what I had done for JET, and now I think I need to throw away the logic in JET as well; JET will just propagate Any for non-constant global variables.
Of course this will make JET's profiling less accurate, but it's consistent with Julia's JIT at least, and I feel we want to have performance-warnings for this instead.

2. control flows in toplevel frames

Well, as for toplevel frames, I rather want to keep VirtualGlobalVarible logic. Toplevel call signatures are really important for JET's profiling process, because they're "starting points" of our analysis.
Assuming assignments of global variables only happen in toplevel frames, I would like to improve the accuracy of our virtual global variable assignments.

Consider the following example:

v = rand(Int)
if rand(Bool)
    v = '1'
end

sin(v)

At sin(v), v should be annotated as v::Union{Int,Char} (and thus union-split NoMethodError should be reported), while JET now interprets toplevel code by per-basic-block basis, and only has really naive assignment logic, and so it's annotated as v::Char, which should be fixed anyway.

don't use `Dict` for local cache store

MRE (from f5b38d8):

julia> using JET; report_call(JET.step_expr!, (JET.ConcreteInterpreter, JET.Frame, Any, Bool))
[ Info: Precompiling JET [c3a54625-cd67-489e-a8e7-0a5a0ff4e31b]
ERROR: TypeError: in new, expected UnionAll, got Type{Tuple{Vararg{Int64}}}
Stacktrace:
   [1] Base.Fix2(f::typeof(isequal), x::Type{Tuple{Vararg{Int64, N}} where N})
     @ Base ./operators.jl:1056
   [2] isequal(x::Type)
     @ Base ./operators.jl:1071
   [3] hash(A::Vector{Any}, h::UInt64)
     @ Base ./abstractarray.jl:2457
   [4] hash
     @ ./hashing.jl:18 [inlined]
   [5] hashindex
     @ ./dict.jl:169 [inlined]
   [6] ht_keyindex(h::Dict{Vector{Any}, Vector{JET.InferenceErrorReportCache}}, key::Vector{Any})
     @ Base ./dict.jl:284
   [7] get
     @ ./dict.jl:505 [inlined]
   [8] cache_lookup(linfo::Core.MethodInstance, given_argtypes::Vector{Any}, cache::JET.JETLocalCache)
     @ JET ~/julia/packages/JET/src/jetcache.jl:110
   [9] abstract_call_method_with_const_args(interp::JET.JETInterpreter, rettype::Any, f::Any, argtypes::Vector{Any}, match::Core.MethodMatch, sv::Core.Compiler.InferenceState, edgecycle::Bool)
     @ Core.Compiler ~/julia/packages/JET/src/abstractinterpretation.jl:363
  [10] abstract_call_gf_by_type(interp::JET.JETInterpreter, f::Any, argtypes::Vector{Any}, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ~/julia/packages/JET/src/abstractinterpretation.jl:216
  [11] abstract_call_known(interp::JET.JETInterpreter, f::Any, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1059
  [12] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1100
  [13] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1080
  [14] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1220
  [15] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
     @ JET ~/julia/packages/JET/src/abstractinterpretation.jl:498
  [16] typeinf_local(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1542
  [17] typeinf_nocycle(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1602
  [18] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:214
  [19] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ JET ~/julia/packages/JET/src/typeinfer.jl:77
  [20] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:209
  [21] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ JET ~/julia/packages/JET/src/typeinfer.jl:21
  [22] typeinf_edge(interp::JET.JETInterpreter, method::Method, atypes::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:811
  [23] abstract_call_method(interp::JET.JETInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:516
  [24] abstract_call_method
     @ ~/julia/packages/JET/src/abstractinterpretation.jl:409 [inlined]
  [25] abstract_call_gf_by_type(interp::JET.JETInterpreter, f::Any, argtypes::Vector{Any}, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ~/julia/packages/JET/src/abstractinterpretation.jl:181
--- the last 15 lines are repeated 6 more times ---
 [116] abstract_call_known(interp::JET.JETInterpreter, f::Any, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1059
 [117] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState, max_methods::Int64)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1100
 [118] abstract_call(interp::JET.JETInterpreter, fargs::Vector{Any}, argtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1080
 [119] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1220
 [120] abstract_eval_statement(interp::JET.JETInterpreter, e::Any, vtypes::Vector{Any}, sv::Core.Compiler.InferenceState)
     @ JET ~/julia/packages/JET/src/abstractinterpretation.jl:498
 [121] typeinf_local(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1542
 [122] typeinf_nocycle(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/abstractinterpretation.jl:1602
 [123] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:214
 [124] _typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ JET ~/julia/packages/JET/src/typeinfer.jl:77
 [125] typeinf(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ Core.Compiler ./compiler/typeinfer.jl:209
 [126] typeinf
     @ ~/julia/packages/JET/src/typeinfer.jl:21 [inlined]
 [127] profile_frame!(interp::JET.JETInterpreter, frame::Core.Compiler.InferenceState)
     @ JET ~/julia/packages/JET/src/JET.jl:573
 [128] profile_method_signature!(interp::JET.JETInterpreter, m::Method, atype::Any, sparams::Core.SimpleVector, world::UInt64)
     @ JET ~/julia/packages/JET/src/JET.jl:569
 [129] profile_method_signature!
     @ ~/julia/packages/JET/src/JET.jl:563 [inlined]
 [130] profile_gf_by_type!(interp::JET.JETInterpreter, tt::Type{var"#s298"} where var"#s298"<:Tuple, world::UInt64)
     @ JET ~/julia/packages/JET/src/JET.jl:537
 [131] profile_gf_by_type!(interp::JET.JETInterpreter, tt::Type{var"#s298"} where var"#s298"<:Tuple)
     @ JET ~/julia/packages/JET/src/JET.jl:529
 [132] profile_call(f::Any, types::Any; jetconfigs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
     @ JET ~/julia/packages/JET/src/JET.jl:605
 [133] profile_call
     @ ~/julia/packages/JET/src/JET.jl:596 [inlined]
 [134] #report_call#87
     @ ~/julia/packages/JET/src/JET.jl:614 [inlined]
 [135] report_call(f::Any, types::Any)
     @ JET ~/julia/packages/JET/src/JET.jl:614

False positive type error in `using ..Main`

It seems that JET doesn't like the following code:

struct X
end

module A
using ..Main: X
end

it reports

═════ 1 toplevel error found ═════
┌ @ tmp/demo.jl:5 
│ TypeError: in using, expected Symbol, got a value of type Module
└─────────────────

Release v0.1.0

Deadline: 2021/04/01

TODO:

  • stabilize API (mainly, give consistent naming for entry points, decide which/when to use analyze/profile/report)
  • setup documentation
    • usage
    • internals
  • tag v0.1

[inference] relational anaysis

something like described in this paper: https://www-apr.lip6.fr/~mine/publi/article-monat-al-ecoop20.pdf

I found there're certainly cases where a relational analysis can improve the analysis accuracy:

adapted from https://github.com/JuliaLang/julia/blob/90bea0319ec29e09123ab4c678fa6a30753c8849/base/multidimensional.jl#L126-L133

# comparison
@inline isless(I1::CartesianIndex{N}, I2::CartesianIndex{N}) where {N} = _isless(0, I1.I, I2.I)
@inline function _isless(ret, I1::NTuple{N,Int}, I2::NTuple{N,Int}) where N
    newret = ifelse(ret==0, icmp(I1[N], I2[N]), ret)
    # NOTE relational analysis can exclude a false positive no method error for 
    # `isless(ret, ::Tuple{}, ::NTuple{N,Int})` and `_isless(ret, ::NTuple{N,Int}, ::Tuple{})`
    _isless(newret, 
        Base.front(I1)#=::Union{Tuple{},Tuple{Int,Vararg{Int}}=#,
        Base.front(I2)#=::Union{Tuple{},Tuple{Int,Vararg{Int}}=#)
end
_isless(ret, ::Tuple{}, ::Tuple{}) = ifelse(ret==1, true, false)
icmp(a, b) = ifelse(isless(a,b), 1, ifelse(a==b, 0, -1))

self-profiling result

against b7d057f

julia> begin
           using TypeProfiler
           interp, frame = TypeProfiler.profile_call_gf(methods(TypeProfiler.profile_text).ms[3].sig)
           TypeProfiler.print_reports(stdout, interp.reports)
       end
═════ 9 possible errors found ═════
┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:100 TypeProfiler.#profile_text#108(TypeProfiler.nothing, true, Base.pairs(Core.NamedTuple()), #self#, io, text, filename, mod)
│┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:100 Core.kwfunc(TypeProfiler.report_errors)(Core.apply_type(Core.NamedTuple, (:filter_native_remarks,))(Core.tuple(filter_native_remarks)), TypeProfiler.report_errors, profiling_logger, mod, text, filename)
││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:110 TypeProfiler.#report_errors#110(Core.tuple(kwargs..., _3, _4), args...)
│││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:110 Core.kwfunc(TypeProfiler.report_errors)(Core.tuple(Base.merge(Base.NamedTuple(), kwargs), TypeProfiler.report_errors), args...)
││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:126 TypeProfiler.#report_errors#112(filter_native_remarks, _3, actualmod, text, filename)
│││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:129 TypeProfiler.virtual_process!(text, filename, virtualmod, TypeProfiler.Symbol(actualmod), interp)
││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:61 #self#(s, filename, virtualmod, actualmodsym, interp, TypeProfiler.gen_virtual_process_result())
│││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:67 TypeProfiler.collect_syntax_errors(s, filename)
││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:497 TypeProfiler.push!(reports, report)
│││││││││┌ @ array.jl:934 Base.convert(_, item)
││││││││││ no matching method found for call signature: Base.convert(_::Type{TypeProfiler.SyntaxErrorReport}, item::Nothing)
│││││││││└────────────────
│││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:74 TypeProfiler.virtual_process!(toplevelex, filename, virtualmod, actualmodsym, interp, ret)
││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:158 eval_with_err_handling(virtualmod, x)
│││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:123 TypeProfiler.with_err_handling(#76, Core.getfield(#self#, :eval_err_handler))
││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:469 err_handler(err, st)
│││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:119 TypeProfiler.crop_stacktrace(st, 3)
││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:481 TypeProfiler.crop_stacktrace(#88, st, offset)
│││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:475 TypeProfiler.-(i, offset)
││││││││││││││ for one of the union split cases, no matching method found for signature: TypeProfiler.-(i::Union{Nothing, Int64}, offset::Int64)
│││││││││││││└─────────────────────────────────────────────────────────────────────────
││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:162 TypeProfiler.virtual_process!(newtoplevelex, filename, newvirtualmod, actualmodsym, interp, ret)
│││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/virtualprocess.jl:202 TypeProfiler.profile_toplevel!(interp, virtualmod, src)
││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/TypeProfiler.jl:172 TypeProfiler.profile_frame!(interp, frame)
│││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/abstractinterpretation.jl:526 TypeProfiler.typeinf(interp, frame)
││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/abstractinterpretation.jl:466 TypeProfiler.invoke(TypeProfiler.typeinf, Core.apply_type(TypeProfiler.Tuple, TypeProfiler.AbstractInterpreter, TypeProfiler.InferenceState), interp, frame)
│││││││││││││┌ @ compiler/typeinfer.jl:12 Core.Compiler.typeinf_nocycle(interp, frame)
││││││││││││││┌ @ compiler/abstractinterpretation.jl:1442 Core.Compiler.typeinf_local(interp, frame)
│││││││││││││││┌ @ compiler/abstractinterpretation.jl:1371 Core.Compiler.abstract_eval_statement(interp, Core.Compiler.getindex(Core.Compiler.getproperty(stmt, :args), 2), changes, frame)
││││││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/abstractinterpretation.jl:348 TypeProfiler.invoke(TypeProfiler.abstract_eval_statement, Core.apply_type(TypeProfiler.Tuple, TypeProfiler.AbstractInterpreter, Any, TypeProfiler.VarTable, TypeProfiler.InferenceState), interp, e, vtypes, sv)
│││││││││││││││││┌ @ compiler/abstractinterpretation.jl:1132 Core.Compiler.abstract_call(interp, ea, argtypes, sv)
││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:1010 #self#(interp, fargs, argtypes, sv, Core.Compiler.getproperty(Core.Compiler.InferenceParams(interp), :MAX_METHODS))
│││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:1026 Core.Compiler.abstract_call_known(interp, f, fargs, argtypes, sv, max_methods)
││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:917 Core.Compiler.abstract_apply(interp, Core.Compiler.nothing, ft, Core.Compiler.argtype_tail(argtypes, 3), sv, max_methods)
│││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:665 Core.Compiler.precise_container_type(interp, itft, ti, sv)
││││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:562 Core.Compiler.abstract_iteration(interp, itft, typ, sv)
│││││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:580 Core.Compiler.abstract_call_known(interp, iteratef, Core.Compiler.nothing, Core.Compiler.getindex(Core.Compiler.Any, itft, itertype), sv)
││││││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:911 #self#(interp, f, fargs, argtypes, sv, Core.Compiler.getproperty(Core.Compiler.InferenceParams(interp), :MAX_METHODS))
│││││││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:961 Core.Compiler.abstract_call_gf_by_type(interp, f, Core.Compiler.getindex(Core.Compiler.Any, Core.Compiler.Const(f), Core.Compiler.Bool), Core.apply_type(Core.Compiler.Tuple, Core.Compiler.typeof(f), Core.Compiler.Bool), sv)
││││││││││││││││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/abstractinterpretation.jl:86 #self#(interp, f, argtypes, atype, sv, Core.Compiler.getproperty(Core.Compiler.InferenceParams(interp), :MAX_METHODS))
│││││││││││││││││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/abstractinterpretation.jl:215 Core.Compiler.abstract_call_method(interp, method, sig, Core.Compiler.getproperty(match, :sparams), multiple_matches, sv)
││││││││││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:415 Core.Compiler.max(spec_len, l_comparison)
│││││││││││││││││││││││││││││┌ @ operators.jl:419 Core.Compiler.isless(y, x)
││││││││││││││││││││││││││││││┌ @ operators.jl:169 Core.Compiler.isnan(x)
│││││││││││││││││││││││││││││││ variable Core.Compiler.isnan is not defined: Core.Compiler.isnan(x::AbstractFloat)
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││┌ @ compiler/abstractinterpretation.jl:466 Core.Compiler.typeinf_edge(interp, method, sig, sparams, sv)
│││││││││││││││││││││││││││││┌ @ compiler/typeinfer.jl:526 Core.Compiler.resolve_call_cycle!(interp, mi, caller)
││││││││││││││││││││││││││││││┌ @ compiler/typeinfer.jl:484 Core.Compiler.merge_call_chain!(parent, frame, frame, limited)
│││││││││││││││││││││││││││││││┌ @ compiler/typeinfer.jl:445 Core.Compiler.add_cycle_backedge!(child, parent, Core.Compiler.getproperty(parent, :currpc))
││││││││││││││││││││││││││││││││ for one of the union split cases, no matching method found for signature: Core.Compiler.add_cycle_backedge!(child::Core.Compiler.InferenceState, parent::Union{Nothing, Core.Compiler.InferenceState}, Core.Compiler.getproperty(parent::Union{Nothing, Core.Compiler.InferenceState}, :currpc::Symbol)::Int64)
│││││││││││││││││││││││││││││││└─────────────────────────────
│││││││││││││││││││││││││││││││┌ @ compiler/typeinfer.jl:445 Core.Compiler.add_cycle_backedge!(child, parent, Core.Compiler.getproperty(parent, :currpc))
││││││││││││││││││││││││││││││││ for one of the union split cases, no matching method found for signature: Core.Compiler.add_cycle_backedge!(child::Union{Nothing, Core.Compiler.InferenceState}, parent::Union{Nothing, Core.Compiler.InferenceState}, Core.Compiler.getproperty(parent::Union{Nothing, Core.Compiler.InferenceState}, :currpc::Symbol)::Int64)
│││││││││││││││││││││││││││││││└─────────────────────────────
│││││││││││││││││││││││││││││││┌ @ compiler/typeinfer.jl:446 Core.Compiler.union_caller_cycle!(ancestor, child)
││││││││││││││││││││││││││││││││ for one of the union split cases, no matching method found for signature: Core.Compiler.union_caller_cycle!(ancestor::Core.Compiler.InferenceState, child::Union{Nothing, Core.Compiler.InferenceState})
│││││││││││││││││││││││││││││││└─────────────────────────────
││││││││││││┌ @ compiler/abstractinterpretation.jl:966 Core.Compiler.abstract_call_known(interp, Core.Compiler.===, fargs, argtypes, sv)
│││││││││││││┌ @ compiler/abstractinterpretation.jl:911 #self#(interp, f, fargs, argtypes, sv, Core.Compiler.getproperty(Core.Compiler.InferenceParams(interp), :MAX_METHODS))
││││││││││││││┌ @ compiler/abstractinterpretation.jl:924 Core.Compiler.abstract_call_builtin(interp, f, fargs, argtypes, sv, max_methods)
│││││││││││││││┌ @ compiler/abstractinterpretation.jl:794 Core.Compiler.builtin_tfunction(interp, f, Core.Compiler.getindex(argtypes, Core.Compiler.:(2, Core.Compiler.lastindex(argtypes))), sv)
││││││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/tfuncs.jl:14 Base.getproperty(TypeProfiler.val, :t)
│││││││││││││││││ variable TypeProfiler.val is not defined: Base.getproperty(TypeProfiler.val, :t::Symbol)
││││││││││││││││└────────────────────────────────────────────────────────────────
││││││││││││┌ @ compiler/abstractinterpretation.jl:982 Core.Compiler.abstract_call_known(interp, Core.Compiler.<:, fargs, argtypes, sv)
│││││││││││││┌ @ compiler/abstractinterpretation.jl:911 #self#(interp, f, fargs, argtypes, sv, Core.Compiler.getproperty(Core.Compiler.InferenceParams(interp), :MAX_METHODS))
││││││││││││││┌ @ compiler/abstractinterpretation.jl:924 Core.Compiler.abstract_call_builtin(interp, f, fargs, argtypes, sv, max_methods)
│││││││││││││││┌ @ compiler/abstractinterpretation.jl:794 Core.Compiler.builtin_tfunction(interp, f, Core.Compiler.getindex(argtypes, Core.Compiler.:(2, Core.Compiler.lastindex(argtypes))), sv)
││││││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/tfuncs.jl:14 Base.getproperty(TypeProfiler.val, :t)
│││││││││││││││││ variable TypeProfiler.val is not defined: Base.getproperty(TypeProfiler.val, :t::Symbol)
││││││││││││││││└────────────────────────────────────────────────────────────────
││││││││││││┌ @ compiler/abstractinterpretation.jl:924 Core.Compiler.abstract_call_builtin(interp, f, fargs, argtypes, sv, max_methods)
│││││││││││││┌ @ compiler/abstractinterpretation.jl:794 Core.Compiler.builtin_tfunction(interp, f, Core.Compiler.getindex(argtypes, Core.Compiler.:(2, Core.Compiler.lastindex(argtypes))), sv)
││││││││││││││┌ @ /Users/aviatesk/grad-thesis/TypeProfiler.jl/src/tfuncs.jl:14 Base.getproperty(TypeProfiler.val, :t)
│││││││││││││││ variable TypeProfiler.val is not defined: Base.getproperty(TypeProfiler.val, :t::Symbol)
││││││││││││││└────────────────────────────────────────────────────────────────
true

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.