Repository: JuliaLang/julia
File: base/experimental.jl (Julia)

Code before:
"""
function register_error_hint(@nospecialize(handler), @nospecialize(exct::Type))
    list = get!(Vector{Any}, _hint_handlers, nameof(exct))
    push!(list, handler)
    return nothing
end

const _hint_handlers = IdDict{Symbol,Vector{Any}}()

"""
    Experimental.show_error_hints(io, ex, args...)

Invoke all handlers from [`Experimental.register_error_hint`](@ref) for the particular
exception type `typeof(ex)` and all of its supertypes. `args` must contain any other arguments expected by
the handler for that type.

!!! compat "Julia 1.5"
    Custom error hints are available as of Julia 1.5.
!!! warning
    This interface is experimental and subject to change or removal without notice.
"""
function show_error_hints(io, ex, args...)
    @nospecialize
    ex_supertype = typeof(ex)
    while ex_supertype != Any
        hinters = get(_hint_handlers, ex_supertype, nothing)
        isnothing(hinters) && continue
        for handler in hinters
            try
                # TODO: deal with handlers accepting different signatures?
                @invokelatest handler(io, ex, args...)
            catch
                tn = typeof(handler).name
                @error "Hint-handler $handler for $(ex_supertype) in $(tn.module) caused an error" exception=current_exceptions()
            end
        end
        ex_supertype = supertype(ex_supertype)
    end
end

# OpaqueClosure
include("opaque_closure.jl")

"""
    Base.Experimental.@overlay mt def

Define a method and add it to the method table `mt` instead of to the global method table.
This can be used to implement a method override mechanism. Regular compilation will not
consider these methods, and you should customize the compilation flow to look in these
method tables (e.g., using [`Core.Compiler.OverlayMethodTable`](@ref)).


Review comment (suggestion):
```suggestion
        hinters = get(_hint_handlers, typename(ex_supertype), nothing)
```

Code after:
"""
function register_error_hint(@nospecialize(handler), @nospecialize(exct::Type))
    list = get!(Vector{Any}, _hint_handlers, Core.typename(exct))
    push!(list, (exct, handler))
    return nothing
end

const _hint_handlers = IdDict{Core.TypeName,Vector{Any}}()

"""
    Experimental.show_error_hints(io, ex, args...)

Invoke all handlers from [`Experimental.register_error_hint`](@ref) for the particular
exception type `typeof(ex)` and all of its supertypes. `args` must contain any other arguments expected by
the handler for that type.

!!! compat "Julia 1.5"
    Custom error hints are available as of Julia 1.5.
!!! warning
    This interface is experimental and subject to change or removal without notice.
"""
function show_error_hints(io, ex, args...)
    @nospecialize
    ex_supertype = typeof(ex)
    while ex_supertype != Any
        hinters = get(_hint_handlers, Core.typename(ex_supertype), Any[])
        for (exct, handler) in hinters
            ex isa exct || continue
            try
                # TODO: deal with handlers accepting different signatures?
                @invokelatest handler(io, ex, args...)
            catch
                tn = typeof(handler).name
                @error "Hint-handler $handler for $(ex_supertype) in $(tn.module) caused an error" exception=current_exceptions()
            end
        end
        ex_supertype = supertype(ex_supertype)
    end
end

# OpaqueClosure
include("opaque_closure.jl")

"""
    Base.Experimental.@overlay mt def

Define a method and add it to the method table `mt` instead of to the global method table.
This can be used to implement a method override mechanism. Regular compilation will not
consider these methods, and you should customize the compilation flow to look in these
method tables (e.g., using [`Core.Compiler.OverlayMethodTable`](@ref)).