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

Code before:
    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)).

!!! note
    Please be aware that when defining overlay methods using `@overlay`, it is not necessary

Review comment (suggestion):
```suggestion
        for handler in 1:2:length(hinters)
            ex isa hinters[handler] || continue
            handler = hinters[handler + 1]
```

Code after:
    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)).

!!! note
    Please be aware that when defining overlay methods using `@overlay`, it is not necessary