diff --git a/src/piracy.jl b/src/piracy.jl index e29018bf..5375ea7e 100644 --- a/src/piracy.jl +++ b/src/piracy.jl @@ -162,14 +162,25 @@ function is_pirate(meth::Method; treat_as_own = Union{Function,Type}[]) signature = Base.unwrap_unionall(meth.sig) + function_type_index = 1 + if signature.parameters[1] === typeof(Core.kwcall) + # kwcall is a special case, since it is not a real function + # but a wrapper around a function, the third parameter is the original + # function, its positional arguments follow. + function_type_index += 2 + end + # the first parameter in the signature is the function type, and it # follows slightly other rules if it happens to be a Union type - is_foreign_method(signature.parameters[1], method_pkg; treat_as_own = treat_as_own) || - return false + is_foreign_method( + signature.parameters[function_type_index], + method_pkg; + treat_as_own = treat_as_own, + ) || return false - all( + return all( param -> is_foreign(param, method_pkg; treat_as_own = treat_as_own), - signature.parameters[2:end], + signature.parameters[function_type_index+1:end], ) end diff --git a/test/test_piracy.jl b/test/test_piracy.jl index 78de01d3..2ba30df3 100644 --- a/test/test_piracy.jl +++ b/test/test_piracy.jl @@ -37,6 +37,7 @@ Base.findlast(::ForeignParameterizedType{Foo}, x::Int) = x + 1 # Not piracy const MyUnion = Union{Int,Foo} MyUnion(x::Int) = x +MyUnion(; x::Int) = x export MyUnion @@ -71,7 +72,7 @@ end 2 + # Foo constructors 1 + # Bar constructor 2 + # f - 1 + # MyUnion + 4 + # MyUnion (incl. kwcall) 6 + # findlast 3 + # findfirst 1 + # ForeignType callable