Fatal: error thrown and no exception handler available for a * method

This is an MWE simplified from some code that tries to implement * for a type and AbstractStrings. In this MWE, the intention is to return a Foo whenever any argument is a Foo.

Is this a bug, or user error? I think that the * method should be more specific than the *(s1::Union{AbstractChar, AbstractString}, ss::Union{AbstractChar, AbstractString}...) in Base, so I am not sure why it is causing a problem.

julia> VERSION
v"1.9.3-DEV.0"

julia> struct Foo end

julia> Base.:(*)(::Foo, ::AbstractString...) = Foo()

julia> Base.:(*)(::AbstractString, ::Union{AbstractString,Foo}...) = Foo()

fatal: error thrown and no exception handler available.
MethodError(f=Base.:(*), args=("", "", "", "", "", ""), world=0x00000000000082c3)
jl_method_error_bare at /home/tamas/src/julia-1.9/src/gf.c:2076
jl_method_error at /home/tamas/src/julia-1.9/src/gf.c:2094
jl_lookup_generic_ at /home/tamas/src/julia-1.9/src/gf.c:2921 [inlined]
ijl_apply_generic at /home/tamas/src/julia-1.9/src/gf.c:2936
#with_output_color#962 at ./util.jl:87
with_output_color at ./util.jl:71 [inlined]
#printstyled#963 at ./util.jl:130 [inlined]
printstyled at ./util.jl:130
unknown function (ip: 0x7fb17932841d)
display_error at ./client.jl:110
unknown function (ip: 0x7fb179327b56)
display_error at ./client.jl:114
unknown function (ip: 0x7fb179327922)
jl_apply at /home/tamas/src/julia-1.9/src/julia.h:1879 [inlined]
jl_f__call_latest at /home/tamas/src/julia-1.9/src/builtins.c:774
#invokelatest#2 at ./essentials.jl:816 [inlined]
invokelatest at ./essentials.jl:813 [inlined]
_start at ./client.jl:524
jfptr__start_43091 at /home/tamas/src/julia-1.9/usr/lib/julia/sys.so (unknown line)
jl_apply at /home/tamas/src/julia-1.9/src/julia.h:1879 [inlined]
true_main at /home/tamas/src/julia-1.9/src/jlapi.c:573
jl_repl_entrypoint at /home/tamas/src/julia-1.9/src/jlapi.c:717
main at julia (unknown line)
unknown function (ip: 0x7fb1936daa8f)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at julia (unknown line)
1 Like

:rofl: :joy:
:kissing_heart:

It’s actually ambiguous for *(::String, ::String), you can see the MethodError by making a new function with the argument signatures. But throwing the MethodError required a *(::String, ::String) call, so if that fails due to type piracy, we’re stuck.

That seems to work for me.

julia> struct Foo end

julia> f(::Foo, ::AbstractString...) = Foo()
f (generic function with 1 method)

julia> f(::AbstractString, ::Union{AbstractString,Foo}...) = Foo()
f (generic function with 2 methods)

julia> f(a::AbstractString, b::AbstractString...) = string(a, b...)
f (generic function with 3 methods)

julia> 

julia> f(Foo(), "a")
Foo()

julia> f("a", Foo(), "a")
Foo()

julia> f("a", "b", "a")
"aba"

Like you said, Base doesn’t have a *(::AbstractString, ::AbstractString...) method. Replace that 3rd method and you find:

julia> f(s1::Union{AbstractChar, AbstractString}, ss::Union{AbstractChar, AbstractString}...) = 0
f (generic function with 3 methods)

julia> f("h", "i")
ERROR: MethodError: f(::String, ::String) is ambiguous. Candidates:

Dispatch issues are expected from the type piracy the 2nd method does.

2 Likes

Thanks! I overlooked that.