Weird error after defining Base.show method for custom DataType

I don’t know if defining a new method of Base.show for a custom type (the type itself and not it instances) is something that someone shouldn’t do, but basically: i have a type Operator{T} where T is a Symbol, and instead of showing Operator{:(=)}, for example, every time the type gets printed in the console, i want it to show Operator{=}, so i defined a new method of Base.show, and it works, however, when the type should be printed in a exception, i get “showing an error caused an error”. I’ll let the code speak for itself:

julia> macro Operator_str(str)
           sym = QuoteNode(Symbol(str))
           Expr(:curly, :Operator, sym)
       end
@Operator_str (macro with 1 method)

julia> struct Operator{T}
           args::Vector
       end

julia> equals = Operator"="([:a, :b])
Operator{:(=)}([:a, :b])

julia> Operator"*"
Operator{:*}

julia> function Base.show(io::IO, ::Type{Operator{T}}) where {T}
           print(io, "Operator{$T}")
       end

julia> equals
Operator{=}([:a, :b])

julia> Operator"*"
Operator{*}

julia> Operator"|"()
ERROR: MethodError: no method matching Operator{|}()
Stacktrace:
 [1] top-level scope
   @ REPL[8]:1
SYSTEM (REPL): showing an error caused an error
ERROR: UndefVarError: T not defined
Stacktrace:
  [1] show(io::IOContext{IOBuffer}, #unused#::
SYSTEM (REPL): caught exception of type UndefVarError while trying to handle a nested exception; giving up

Also, when running the code outside the REPL i get this:

julia ./test.jl
equals = Operator{:(=)}([:a, :b])
equals = Operator{=}([:a, :b])
Operator"|" = Operator{|}
ERROR: LoadError: MethodError: no method matching Operator{|}()
Stacktrace:
 [1] top-level scope
   @ C:\Users\jorge\dev\test.jl:20ERROR: UndefVarError: T not defined
Stacktrace:
  [1] show(io::IOContext{IOBuffer}, #unused#::fatal: error thrown and no exception handler available.
UndefVarError(var=:T)
jl_undefined_var_error at /cygdrive/c/buildbot/worker/package_win64/build/src\rtutils.c:132
show at C:\Users\jorge\dev\test.jl:14
show_typeparams at .\show.jl:640
show_datatype at .\show.jl:1011
show_datatype at .\show.jl:989 [inlined]
_show_type at .\show.jl:889
jfptr__show_type_38169.clone_1 at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\lib\julia\sys.dll (unknown line)
show at .\show.jl:881
jfptr_show_33170.clone_1 at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\lib\julia\sys.dll (unknown line)
#sprint#426 at .\strings\io.jl:112
sprint##kw at .\strings\io.jl:108 [inlined]
#print_type_stacktrace#485 at .\show.jl:2399
print_type_stacktrace at .\show.jl:2399
jfptr_print_type_stacktrace_31920.clone_1 at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\lib\julia\sys.dll (unknown line)
#show_tuple_as_call#484 at .\show.jl:2380
show_tuple_as_call##kw at .\show.jl:2353
jfptr_show_tuple_as_callYY.YY.kw_46476.clone_1 at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\lib\julia\sys.dll (unknown line)
show_spec_linfo at .\stacktraces.jl:244
print_stackframe at .\errorshow.jl:709
print_stackframe at .\errorshow.jl:685
#show_full_backtrace#834 at .\errorshow.jl:574
show_full_backtrace##kw at .\errorshow.jl:565 [inlined]
show_backtrace at .\errorshow.jl:769
#showerror#813 at .\errorshow.jl:90
showerror##kw at .\errorshow.jl:87
unknown function (ip: 000000005f01f123)
show_exception_stack at .\errorshow.jl:866
display_error at .\client.jl:104
unknown function (ip: 000000005f013764)
display_error at .\client.jl:107
unknown function (ip: 000000005f0131e0)
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1788 [inlined]
jl_f__call_latest at /cygdrive/c/buildbot/worker/package_win64/build/src\builtins.c:757
#invokelatest#2 at .\essentials.jl:716 [inlined]
invokelatest at .\essentials.jl:714 [inlined]
_start at .\client.jl:497
jfptr__start_21275.clone_1 at C:\Users\jorge\AppData\Local\Programs\Julia-1.7.2\lib\julia\sys.dll (unknown line)
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1788 [inlined]
true_main at /cygdrive/c/buildbot/worker/package_win64/build/src\jlapi.c:559
jl_repl_entrypoint at /cygdrive/c/buildbot/worker/package_win64/build/src\jlapi.c:701
mainCRTStartup at /cygdrive/c/buildbot/worker/package_win64/build/cli\loader_exe.c:42
BaseThreadInitThunk at C:\Windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\Windows\SYSTEM32\ntdll.dll (unknown line)

The workaround that i found for this problem is:

julia> function Base.show(io::IO, type::Type{<:Operator})
           T = first(type.parameters)
           print(io, "Operator{$T}")
       end

julia> equals
Operator{=}([:a, :b])

julia> Operator"|"
Operator{|}

julia> Operator"|"()
ERROR: MethodError: no method matching Operator{|}()
Closest candidates are:
  Operator{T}(::Any) where T at REPL[2]:2
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

So my question is: is this a bug or i shouldn’t define Base.show for a specific DataType?

Yes. Can’t find the issue atm, but, as you can see, doing that can be pretty dangerous.

Thanks for your answer. Another question, wouldn’t be helpful if Julia detects when a user tries to do something like this, so the user can know that he/she shouldn’t do that?