diff --git a/src/gf.c b/src/gf.c index a488c09f5ea41..4b77da21d9911 100644 --- a/src/gf.c +++ b/src/gf.c @@ -938,14 +938,9 @@ static void jl_compilation_sig( int notcalled_func = (i_arg > 0 && i_arg <= 8 && !(definition->called & (1 << (i_arg - 1))) && !jl_has_free_typevars(decl_i) && jl_subtype(elt, (jl_value_t*)jl_function_type)); - if (notcalled_func && (type_i == (jl_value_t*)jl_any_type || - type_i == (jl_value_t*)jl_function_type || - (jl_is_uniontype(type_i) && // Base.Callable - ((((jl_uniontype_t*)type_i)->a == (jl_value_t*)jl_function_type && - ((jl_uniontype_t*)type_i)->b == (jl_value_t*)jl_type_type) || - (((jl_uniontype_t*)type_i)->b == (jl_value_t*)jl_function_type && - ((jl_uniontype_t*)type_i)->a == (jl_value_t*)jl_type_type))))) { - // and attempt to despecialize types marked Function, Callable, or Any + if (notcalled_func && (jl_subtype((jl_value_t*)jl_function_type, type_i))) { + // and attempt to despecialize types marked as a supertype of Function (i.e. + // Function, Callable, Any, or a Union{Function, T}) // when called with a subtype of Function but is not called if (!*newparams) *newparams = jl_svec_copy(tt->parameters); jl_svecset(*newparams, i, (jl_value_t*)jl_function_type); @@ -1174,15 +1169,9 @@ JL_DLLEXPORT int jl_isa_compileable_sig( int notcalled_func = (i_arg > 0 && i_arg <= 8 && !(definition->called & (1 << (i_arg - 1))) && !jl_has_free_typevars(decl_i) && jl_subtype(elt, (jl_value_t*)jl_function_type)); - if (notcalled_func && (type_i == (jl_value_t*)jl_any_type || - type_i == (jl_value_t*)jl_function_type || - (jl_is_uniontype(type_i) && // Base.Callable - ((((jl_uniontype_t*)type_i)->a == (jl_value_t*)jl_function_type && - ((jl_uniontype_t*)type_i)->b == (jl_value_t*)jl_type_type) || - (((jl_uniontype_t*)type_i)->b == (jl_value_t*)jl_function_type && - ((jl_uniontype_t*)type_i)->a == (jl_value_t*)jl_type_type))))) { - // and attempt to despecialize types marked Function, Callable, or Any - // when called with a subtype of Function but is not called + if (notcalled_func && jl_subtype((jl_value_t*)jl_function_type, type_i)) { + // and attempt to despecialize types marked as a supertype of Function (i.e. + // Function, Callable, Any, or a Union{Function, T}) if (elt == (jl_value_t*)jl_function_type) continue; JL_GC_POP(); diff --git a/test/core.jl b/test/core.jl index 4ccf4e15d1acd..5879587943726 100644 --- a/test/core.jl +++ b/test/core.jl @@ -233,6 +233,62 @@ k11840(::Type{Union{Tuple{Int32}, Tuple{Int64}}}) = '2' @test k11840(Tuple{Union{Int32, Int64}}) == '2' @test k11840(Union{Tuple{Int32}, Tuple{Int64}}) == '2' +# issue #59327 +@noinline f59327(f, x) = Any[f, x] +g59327(x) = f59327(+, Any[x][1]) +g59327(1) +@test any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(f59327), Function, Int}, + methods(f59327)[1].specializations) + +@noinline h59327(f::Union{Function, Nothing}, x) = Any[f, x] +i59327(x) = h59327(+, Any[x][1]) +i59327(1) +@test any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(h59327), Function, Int}, + methods(h59327)[1].specializations) + +@noinline j59327(f::Function, x) = Any[f, x] +k59327(x) = j59327(+, Any[x][1]) +k59327(1) +@test any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(j59327), Function, Int}, + methods(j59327)[1].specializations +) + +@noinline l59327(f::Base.Callable, x) = Any[f, x] +m59327(x) = l59327(+, Any[x][1]) +m59327(1) +@test any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(l59327), Function, Int}, + methods(l59327)[1].specializations +) + +# _do_ specialize if the signature has a `where` +@noinline n59327(f::F, x) where F = Any[f, x] +o59327(x) = n59327(+, Any[x][1]) +o59327(1) +@test !any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(n59327), Function, Int}, + methods(n59327)[1].specializations +) +@test any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(n59327), typeof(+), Int}, + methods(n59327)[1].specializations +) + +# _do_ specialize if the signature is specific +@noinline n59327(f::typeof(+), x) = Any[f, x] +o59327(x) = n59327(+, Any[x][1]) +o59327(1) +@test !any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(n59327), Function, Int}, + methods(n59327)[1].specializations +) +@test any( + mi->mi isa Core.MethodInstance && mi.specTypes == Tuple{typeof(n59327), typeof(+), Int}, + methods(n59327)[1].specializations +) # issue #20511 f20511(x::DataType) = 0