diff --git a/base/boot.jl b/base/boot.jl index 1933e511210c5..cd3ae8b4909bb 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -236,7 +236,7 @@ eval(m::Module, e::ANY) = ccall(:jl_toplevel_eval_in, Any, (Any, Any), m, e) kwfunc(f::ANY) = ccall(:jl_get_keyword_sorter, Any, (Any,), f) -kwftype(t::ANY) = typeof(ccall(:jl_get_kwsorter, Any, (Any,), t.name)) +kwftype(t::ANY) = typeof(ccall(:jl_get_kwsorter, Any, (Any,), t)) mutable struct Box contents::Any diff --git a/src/dump.c b/src/dump.c index 7959f4c390b60..f227cc674c73e 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1366,7 +1366,7 @@ static jl_value_t *jl_deserialize_datatype(jl_serializer_state *s, int pos, jl_v } if (tag == 9) { jl_datatype_t *primarydt = (jl_datatype_t*)jl_deserialize_value(s, NULL); - jl_value_t *dtv = jl_typeof(jl_get_kwsorter(primarydt->name)); + jl_value_t *dtv = jl_typeof(jl_get_kwsorter((jl_value_t*)primarydt)); backref_list.items[pos] = dtv; return dtv; } diff --git a/src/gf.c b/src/gf.c index 84a2bcb3923dc..79b6ea7ca7567 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2402,8 +2402,12 @@ jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_ return (jl_function_t*)f; } -JL_DLLEXPORT jl_function_t *jl_get_kwsorter(jl_typename_t *tn) +JL_DLLEXPORT jl_function_t *jl_get_kwsorter(jl_value_t *ty) { + jl_datatype_t *dt = jl_argument_datatype(ty); + if (dt == NULL) + jl_error("cannot get keyword sorter for abstract type"); + jl_typename_t *tn = dt->name; jl_methtable_t *mt = tn->mt; if (!mt->kwsorter) { JL_LOCK(&mt->writelock); diff --git a/src/julia.h b/src/julia.h index 89ee52892a7d8..fbb9e8ea0ad14 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1038,7 +1038,7 @@ JL_DLLEXPORT void jl_method_def(jl_svec_t *argdata, jl_code_info_t *f, jl_value_ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo); JL_DLLEXPORT jl_code_info_t *jl_copy_code_info(jl_code_info_t *src); JL_DLLEXPORT size_t jl_get_world_counter(void); -JL_DLLEXPORT jl_function_t *jl_get_kwsorter(jl_typename_t *tn); +JL_DLLEXPORT jl_function_t *jl_get_kwsorter(jl_value_t *ty); JL_DLLEXPORT jl_value_t *jl_box_bool(int8_t x); JL_DLLEXPORT jl_value_t *jl_box_int8(int8_t x); JL_DLLEXPORT jl_value_t *jl_box_uint8(uint8_t x); diff --git a/src/julia_internal.h b/src/julia_internal.h index 135d6c5655021..1d7c4ecd171a7 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -375,6 +375,7 @@ jl_method_instance_t *jl_method_lookup(jl_methtable_t *mt, jl_value_t **args, si jl_value_t *jl_gf_invoke(jl_tupletype_t *types, jl_value_t **args, size_t nargs); JL_DLLEXPORT jl_datatype_t *jl_first_argument_datatype(jl_value_t *argtypes); +jl_datatype_t *jl_argument_datatype(jl_value_t *argt); jl_value_t *jl_nth_slot_type(jl_value_t *sig, size_t i); void jl_compute_field_offsets(jl_datatype_t *st); diff --git a/src/method.c b/src/method.c index 40fe7ec9ff31e..d9b98aecd1f8f 100644 --- a/src/method.c +++ b/src/method.c @@ -576,6 +576,12 @@ JL_DLLEXPORT jl_datatype_t *jl_first_argument_datatype(jl_value_t *argtypes) return first_arg_datatype(argtypes, 0); } +// get DataType implied by a single given type +jl_datatype_t *jl_argument_datatype(jl_value_t *argt) +{ + return first_arg_datatype(argt, 1); +} + extern tracer_cb jl_newmeth_tracer; JL_DLLEXPORT void jl_method_def(jl_svec_t *argdata, jl_code_info_t *f, diff --git a/test/keywordargs.jl b/test/keywordargs.jl index e724448d88374..e3806fc87509f 100644 --- a/test/keywordargs.jl +++ b/test/keywordargs.jl @@ -248,3 +248,13 @@ f7045(x::Real; y=true) = y ? 2 : 3 @test f7045(1.0) === 1 @test f7045(1, y=false) === 3 @test f7045(1.0, y=false) === 3 + +# issue #20804 +struct T20804{T} + y::T +end +(f::T20804)(;x=10) = f.y + x +let x = T20804(4) + @test x() == 14 + @test x(x=8) == 12 +end