Skip to content

Conversation

@aviatesk
Copy link
Owner

@aviatesk aviatesk commented Sep 26, 2025

Add primitive integration with JuliaLowering

This implements a very basic integration with JL.

You can retrieve inferred trees in the following way:

julia> using JET, JuliaSyntax

julia> result = @report_call sum("julia")
═════ 2 possible errors found ═════
┌ sum(a::String) @ Base ./reduce.jl:553
│┌ sum(a::String; kw::@Kwargs{}) @ Base ./reduce.jl:553
││┌ sum(f::typeof(identity), a::String) @ Base ./reduce.jl:524
│││┌ sum(f::typeof(identity), a::String; kw::@Kwargs{}) @ Base ./reduce.jl:524
││││┌ mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String) @ Base ./reduce.jl:299
│││││┌ mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String; kw::@Kwargs{}) @ Base ./reduce.jl:299
││││││┌ mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String) @ Base ./reduce.jl:167
│││││││┌ mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String; init::Base._InitialValue) @ Base ./reduce.jl:167
││││││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(Base.add_sum), nt::Base._InitialValue, itr::String) @ Base ./:36
│││││││││┌ foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Base._InitialValue, itr::String) @ Base ./:40
││││││││││┌ _foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, init::Base._InitialValue, itr::String) @ Base ./reduce.jl:54
│││││││││││┌ (::Base.BottomRF{typeof(Base.add_sum)})(acc::Char, x::Char) @ Base ./:78
││││││││││││┌ add_sum(x::Char, y::Char) @ Base ./:16
│││││││││││││ no matching method found `+(::Char, ::Char)`: (x::Char + y::Char)
││││││││││││└────────────────────
│││││││││┌ foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Base._InitialValue, itr::String) @ Base ./:41
││││││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(Base.add_sum)}, itr::String) @ Base ./:372
│││││││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(Base.add_sum)}, itr::String, ::Base.HasEltype) @ Base ./:373
││││││││││││┌ reduce_empty(op::Base.BottomRF{typeof(Base.add_sum)}, ::Type{Char}) @ Base ./:349
│││││││││││││┌ reduce_empty(::typeof(Base.add_sum), ::Type{Char}) @ Base ./:342
││││││││││││││┌ reduce_empty(::typeof(+), ::Type{Char}) @ Base ./:335
│││││││││││││││ no matching method found `zero(::Type{Char})`: zero(T::Type{Char})
││││││││││││││└────────────────────

julia> inferred = JET.get_trees(result, :add_sum)
1-element Vector{JuliaLowering.SyntaxTree}:
 (method core.nothing %₈ (code_info (block Base.+ (call %₁ slot₂/x slot₃/y) (return %₂))))

julia> JuliaSyntax.sourcetext(inferred[1])
"add_sum(x, y) = x + y"

There are several things to note:

  • Please run Pkg.instantiate() after checking out to this branch to
    install JL
  • I couldn't think of a good way to integrate this system with the existing
    cache system, so for now I disabled all the global cache for now on
    this branch.
  • In cases where retrieval of the JL.SyntaxTree corresponding to the
    target CodeInfo for inference fails, no inferred tree will exist.
    Currently, retrieval likely doesn't work well for keyword methods and
    methods with default arguments eit

@aviatesk aviatesk force-pushed the avi/JL-integration branch 6 times, most recently from 0e1d87b to 8054b1f Compare October 2, 2025 12:13
This implements a very basic integration with JL.

You can retrieve inferred trees in the following way:
```julia
julia> using JET, JuliaSyntax

julia> result = @report_call sum("julia")
═════ 2 possible errors found ═════
┌ sum(a::String) @ Base ./reduce.jl:553
│┌ sum(a::String; kw::@kwargs{}) @ Base ./reduce.jl:553
││┌ sum(f::typeof(identity), a::String) @ Base ./reduce.jl:524
│││┌ sum(f::typeof(identity), a::String; kw::@kwargs{}) @ Base ./reduce.jl:524
││││┌ mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String) @ Base ./reduce.jl:299
│││││┌ mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String; kw::@kwargs{}) @ Base ./reduce.jl:299
││││││┌ mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String) @ Base ./reduce.jl:167
│││││││┌ mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String; init::Base._InitialValue) @ Base ./reduce.jl:167
││││││││┌ mapfoldl_impl(f::typeof(identity), op::typeof(Base.add_sum), nt::Base._InitialValue, itr::String) @ Base ./:36
│││││││││┌ foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Base._InitialValue, itr::String) @ Base ./:40
││││││││││┌ _foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, init::Base._InitialValue, itr::String) @ Base ./reduce.jl:54
│││││││││││┌ (::Base.BottomRF{typeof(Base.add_sum)})(acc::Char, x::Char) @ Base ./:78
││││││││││││┌ add_sum(x::Char, y::Char) @ Base ./:16
│││││││││││││ no matching method found `+(::Char, ::Char)`: (x::Char + y::Char)
││││││││││││└────────────────────
│││││││││┌ foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Base._InitialValue, itr::String) @ Base ./:41
││││││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(Base.add_sum)}, itr::String) @ Base ./:372
│││││││││││┌ reduce_empty_iter(op::Base.BottomRF{typeof(Base.add_sum)}, itr::String, ::Base.HasEltype) @ Base ./:373
││││││││││││┌ reduce_empty(op::Base.BottomRF{typeof(Base.add_sum)}, ::Type{Char}) @ Base ./:349
│││││││││││││┌ reduce_empty(::typeof(Base.add_sum), ::Type{Char}) @ Base ./:342
││││││││││││││┌ reduce_empty(::typeof(+), ::Type{Char}) @ Base ./:335
│││││││││││││││ no matching method found `zero(::Type{Char})`: zero(T::Type{Char})
││││││││││││││└────────────────────

julia> inferred = JET.get_trees(result, :add_sum)
1-element Vector{JuliaLowering.SyntaxTree}:
 (method core.nothing %₈ (code_info (block Base.+ (call %₁ slot₂/x slot₃/y) (return %₂))))

julia> JuliaSyntax.sourcetext(inferred[1])
"add_sum(x, y) = x + y"
```

There are several things to note:
- Please run `Pkg.instantiate()` after checking out to this branch to
  install JL
- I couldn't think of a good way to integrate this system with the existing
  cache system, so for now I disabled all the global cache for now on
  this branch.
- In cases where retrieval of the `JL.SyntaxTree` corresponding to the
  target `CodeInfo` for inference fails, no inferred tree will exist.
  Currently, retrieval likely doesn't work well for keyword methods and
  methods with default arguments either
ps = ParseStream!(s; rule=:statement)
st0 = JS.build_tree(JL.SyntaxTree, ps; first_line)
stlwr = try
JL.lower(m.module, st0)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
JL.lower(m.module, st0)
JL.lower(m.module, st0; expr_compat_mode=true)

Do we want expr_compat_mode on here? The types of quoted code and the signatures of new macro definitions will be different otherwise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants