Skip to content

Commit 691d310

Browse files
committed
fixes to OpaqueClosure argument count handling and MethodError display
1 parent c5fae67 commit 691d310

File tree

4 files changed

+44
-14
lines changed

4 files changed

+44
-14
lines changed

base/errorshow.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,11 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=()
409409
buf = IOBuffer()
410410
iob0 = iob = IOContext(buf, io)
411411
tv = Any[]
412-
sig0 = method.sig
412+
if func isa Core.OpaqueClosure
413+
sig0 = signature_type(func, typeof(func).parameters[1])
414+
else
415+
sig0 = method.sig
416+
end
413417
while isa(sig0, UnionAll)
414418
push!(tv, sig0.var)
415419
iob = IOContext(iob, :unionall_env => sig0.var)

base/methodshow.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ end
7979

8080
# NOTE: second argument is deprecated and is no longer used
8181
function kwarg_decl(m::Method, kwtype = nothing)
82+
if m.sig === Tuple # OpaqueClosure
83+
return Symbol[]
84+
end
8285
mt = get_methodtable(m)
8386
if isdefined(mt, :kwsorter)
8487
kwtype = typeof(mt.kwsorter)

src/method.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,14 @@ static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_sve
5151
return jl_module_globalref(module, (jl_sym_t*)expr);
5252
}
5353
else if (jl_is_returnnode(expr)) {
54-
jl_value_t *val = resolve_globals(jl_returnnode_value(expr), module, sparam_vals, binding_effects, eager_resolve);
55-
if (val != jl_returnnode_value(expr)) {
56-
JL_GC_PUSH1(&val);
57-
expr = jl_new_struct(jl_returnnode_type, val);
58-
JL_GC_POP();
54+
jl_value_t *retval = jl_returnnode_value(expr);
55+
if (retval) {
56+
jl_value_t *val = resolve_globals(retval, module, sparam_vals, binding_effects, eager_resolve);
57+
if (val != retval) {
58+
JL_GC_PUSH1(&val);
59+
expr = jl_new_struct(jl_returnnode_type, val);
60+
JL_GC_POP();
61+
}
5962
}
6063
return expr;
6164
}

test/opaque_closure.jl

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,21 +244,41 @@ end
244244
using Core.Compiler: IRCode
245245
using Core: CodeInfo
246246

247-
function OC(ir::IRCode, env...)
248-
src = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ());
247+
function OC(ir::IRCode, nargs::Int, isva::Bool, env...)
248+
if (isva && nargs > length(ir.argtypes)) || (!isva && nargs != length(ir.argtypes)-1)
249+
throw(ArgumentError("invalid argument count"))
250+
end
251+
src = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ())
249252
src.slotflags = UInt8[]
250-
nargs = length(ir.argtypes)
251-
src.slotnames = fill(:none, nargs)
252-
Core.Compiler.replace_code_newstyle!(src, ir, nargs);
253-
Core.Compiler.widen_all_consts!(src);
253+
src.slotnames = fill(:none, nargs+1)
254+
Core.Compiler.replace_code_newstyle!(src, ir, nargs+1)
255+
Core.Compiler.widen_all_consts!(src)
254256
src.inferred = true
255257
# NOTE: we need ir.argtypes[1] == typeof(env)
256258

257259
ccall(:jl_new_opaque_closure_from_code_info, Any, (Any, Any, Any, Any, Any, Cint, Any, Cint, Cint, Any),
258-
Tuple{ir.argtypes[2:end]...}, Union{}, Any, @__MODULE__, src, 0, nothing, nargs-1, false, env)
260+
Tuple{ir.argtypes[2:end]...}, Union{}, Any, @__MODULE__, src, 0, nothing, nargs, isva, env)
261+
end
262+
263+
function OC(src::CodeInfo, env...)
264+
M = src.parent.def
265+
sig = Base.tuple_type_tail(src.parent.specTypes)
266+
267+
ccall(:jl_new_opaque_closure_from_code_info, Any, (Any, Any, Any, Any, Any, Cint, Any, Cint, Cint, Any),
268+
sig, Union{}, Any, @__MODULE__, src, 0, nothing, M.nargs - 1, M.isva, env)
259269
end
260270

261271
let ci = code_typed(+, (Int, Int))[1][1]
262272
ir = Core.Compiler.inflate_ir(ci)
263-
@test OC(ir)(40, 2) == 42
273+
@test OC(ir, 2, false)(40, 2) == 42
274+
end
275+
276+
let ci = code_typed((x, y...)->(x, y), (Int, Int))[1][1]
277+
ir = Core.Compiler.inflate_ir(ci)
278+
@test OC(ir, 2, true)(40, 2) === (40, (2,))
279+
end
280+
281+
let ci = code_typed((x, y...)->(x, y), (Int, Int))[1][1]
282+
@test OC(ci)(1, 2) === (1, (2,))
283+
@test_throws MethodError OC(ci)(1, 2, 3)
264284
end

0 commit comments

Comments
 (0)