diff --git a/CHANGELOG.md b/CHANGELOG.md index b963a6b..af8625c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v1.0.5 - unreleased - Some general cleanup of the code, and adding ExplicitImports.jl tests for long term maintainability. +- Fix the error when there is a positional vararg eg. `fn(a...; kw)` (#135) ## v1.0.4 - 2025-08-25 diff --git a/src/utils.jl b/src/utils.jl index 383485b..5fc4e0d 100755 --- a/src/utils.jl +++ b/src/utils.jl @@ -66,8 +66,16 @@ Function returning the slots of a function definition function get_slots(func_def::Dict, args::Dict{Symbol, Any}, mod::Module) slots = Dict{Symbol, Any}() func_def[:name] = gensym() + + if !isempty(func_def[:args]) && !isempty(func_def[:kwargs]) + name, type, splat, default = splitarg(last(func_def[:args])) + # if the final arg is a splat, appending kwargs like we do below causes error + # so set it as non-splat, since we only care about names here anyway + func_def[:args][end] = combinearg(name, type, false, default) + end func_def[:args] = (func_def[:args]..., func_def[:kwargs]...) func_def[:kwargs] = [] + # replace yield with inference barrier func_def[:body] = postwalk(transform_yield, func_def[:body]) # collect items to skip @@ -75,6 +83,7 @@ function get_slots(func_def::Dict, args::Dict{Symbol, Any}, mod::Module) func_def[:body] = postwalk(x->transform_nosave(x, nosaves), func_def[:body]) # eval function func_expr = combinedef(func_def) |> flatten + @debug func_expr |> striplines inferfn = @eval(mod, @noinline $func_expr) #@info func_def[:body] |> striplines # get typed code diff --git a/test/test_main.jl b/test/test_main.jl index 214fa1e..76593f0 100644 --- a/test/test_main.jl +++ b/test/test_main.jl @@ -80,6 +80,18 @@ end @test collect(test_varargs(1, 2, 3)) == [1, 2, 3] end +@resumable function test_varargs_kwargs(a...; k...) + @yield a + @yield k +end + +@testset "test_varargs_kwargs" begin + it = test_varargs_kwargs(1, 2, x=3, y=4) + res = collect(it) + @test res[1] == (1, 2) + @test Dict(res[2]) == Dict(:x => 3, :y => 4) +end + @testset "test_let" begin @resumable function test_let() for u in [[(1,2),(3,4)], [(5,6),(7,8)]]