Skip to content

Commit 0403fd5

Browse files
LiozouKeno
authored andcommitted
Fixed keyword calls to code_macros with keyword arguments (#34367)
1 parent b1e39bc commit 0403fd5

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

stdlib/InteractiveUtils/src/macros.jl

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ import Base: typesof, insert!
66

77
separate_kwargs(args...; kwargs...) = (args, kwargs.data)
88

9-
function gen_call_with_extracted_types(__module__, fcn, ex0)
9+
function gen_call_with_extracted_types(__module__, fcn, ex0, kws=Expr[])
1010
if isa(ex0, Expr)
1111
if any(a->(Meta.isexpr(a, :kw) || Meta.isexpr(a, :parameters)), ex0.args)
1212
return quote
1313
local arg1 = $(esc(ex0.args[1]))
1414
local args, kwargs = $separate_kwargs($(map(esc, ex0.args[2:end])...))
1515
$(fcn)(Core.kwfunc(arg1),
16-
Tuple{typeof(kwargs), Core.Typeof(arg1), map(Core.Typeof, args)...})
16+
Tuple{typeof(kwargs), Core.Typeof(arg1), map(Core.Typeof, args)...};
17+
$(kws...))
1718
end
1819
elseif ex0.head === :call
1920
return Expr(:call, fcn, esc(ex0.args[1]),
20-
Expr(:call, typesof, map(esc, ex0.args[2:end])...))
21+
Expr(:call, typesof, map(esc, ex0.args[2:end])...),
22+
kws...)
2123
elseif ex0.head === :(=) && length(ex0.args) == 2
2224
lhs, rhs = ex0.args
2325
if isa(lhs, Expr)
@@ -95,25 +97,20 @@ of the form "foo=bar" are passed on to the called function as well.
9597
The keyword arguments must be given before the mandatory argument.
9698
"""
9799
function gen_call_with_extracted_types_and_kwargs(__module__, fcn, ex0)
98-
kwargs = Vector{Any}[]
100+
kws = Expr[]
99101
arg = ex0[end] # Mandatory argument
100102
for i in 1:length(ex0)-1
101103
x = ex0[i]
102104
if x isa Expr && x.head === :(=) # Keyword given of the form "foo=bar"
103-
push!(kwargs, x.args)
105+
if length(x.args) != 2
106+
return Expr(:call, :error, "Invalid keyword argument: $x")
107+
end
108+
push!(kws, Expr(:kw, x.args[1], x.args[2]))
104109
else
105110
return Expr(:call, :error, "@$fcn expects only one non-keyword argument")
106111
end
107112
end
108-
thecall = gen_call_with_extracted_types(__module__, fcn, arg)
109-
for kwarg in kwargs
110-
if length(kwarg) != 2
111-
x = string(Expr(:(=), kwarg...))
112-
return Expr(:call, :error, "Invalid keyword argument: $x")
113-
end
114-
push!(thecall.args, Expr(:kw, kwarg[1], kwarg[2]))
115-
end
116-
return thecall
113+
return gen_call_with_extracted_types(__module__, fcn, arg, kws)
117114
end
118115

119116
for fname in [:which, :less, :edit, :functionloc]

stdlib/InteractiveUtils/test/runtests.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ let _true = Ref(true), f, g, h
272272
@test_throws ErrorException h()
273273
end
274274

275+
# Issue #33163
276+
A33163(x; y) = x + y
277+
B33163(x) = x
278+
@test (@code_typed A33163(1, y=2))[1].inferred
279+
@test !(@code_typed optimize=false A33163(1, y=2))[1].inferred
280+
@test !(@code_typed optimize=false B33163(1))[1].inferred
281+
275282
module ReflectionTest
276283
using Test, Random, InteractiveUtils
277284

0 commit comments

Comments
 (0)