diff --git a/src/Tricks.jl b/src/Tricks.jl index 5ad21b6..4a71a5d 100644 --- a/src/Tricks.jl +++ b/src/Tricks.jl @@ -22,9 +22,9 @@ module Tricks """ @generated function static_hasmethod(@nospecialize(f), @nospecialize(t::Type{T}),) where {T<:Tuple} # The signature type: - typ = rewrap_unionall(Tuple{f, unwrap_unionall(T).parameters...}, T) world = typemax(UInt) - method_doesnot_exist = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), typ, world) === nothing + method_insts = Core.Compiler.method_instances(f.instance, T, world) + method_doesnot_exist = isempty(method_insts) ret_func = method_doesnot_exist ? _hasmethod_false : _hasmethod_true ci_orig = uncompressed_ast(typeof(ret_func).name.mt.defs.func) ci = ccall(:jl_copy_code_info, Ref{CodeInfo}, (Any,), ci_orig) @@ -33,7 +33,10 @@ module Tricks if method_doesnot_exist # No method so attach to method table mt = f.name.mt + typ = rewrap_unionall(Tuple{f, unwrap_unionall(T).parameters...}, T) ci.edges = Core.Compiler.vect(mt, typ) + else # method exists, attach edges to all instances + ci.edges = method_insts end return ci end diff --git a/test/runtests.jl b/test/runtests.jl index 929fc10..01f555f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,7 +8,7 @@ iterableness_static(::Type{T}) where T = static_hasmethod(iterate, Tuple{T}) ? I struct Foo end @testset "static_hasmethod" begin - @testset "positive" for data in ( + @testset "positive: $(typeof(data))" for data in ( "abc", [1,2,3], (2,3), ones(4,10,2), 'a', 1:100 ) T = typeof(data) @@ -17,7 +17,7 @@ struct Foo end @test code_typed_ir == [:(return $(QuoteNode(Iterable())))] end - @testset "negative" for data in ( + @testset "negative: $(typeof(data))" for data in ( :a, rand, Int ) T = typeof(data) @@ -44,6 +44,6 @@ struct Foo end Base.delete_method(meth) @test_throws MethodError collect(Foo()) - @test_broken iterableness_static(Foo) === NonIterable() + @test iterableness_static(Foo) === NonIterable() end end