Repository: JuliaLang/julia
File: stdlib/Test/src/Test.jl (Julia)

Code before:
"""
    detect_ambiguities(mod1, mod2...; recursive=false,
                                      ambiguous_bottom=false,
                                      allowed_undefineds=nothing)

Return a vector of `(Method,Method)` pairs of ambiguous methods
defined in the specified modules.
Use `recursive=true` to test in all submodules.

`ambiguous_bottom` controls whether ambiguities triggered only by
`Union{}` type parameters are included; in most cases you probably
want to set this to `false`. See [`Base.isambiguous`](@ref).

See [`Test.detect_unbound_args`](@ref) for an explanation of
`allowed_undefineds`.

!!! compat "Julia 1.8"
    `allowed_undefineds` requires at least Julia 1.8.
"""
function detect_ambiguities(mods::Module...;
                            recursive::Bool = false,
                            ambiguous_bottom::Bool = false,
                            allowed_undefineds = nothing)
    @nospecialize
    ambs = Set{Tuple{Method,Method}}()
    mods = collect(mods)::Vector{Module}
    function sortdefs(m1::Method, m2::Method)
        ord12 = cmp(m1.file, m2.file)
        if ord12 == 0
            ord12 = cmp(m1.line, m2.line)
        end
        return ord12 <= 0 ? (m1, m2) : (m2, m1)
    end
    function examine(mt::Core.MethodTable)
        for m in Base.MethodList(mt)
            is_in_mods(parentmodule(m), recursive, mods) || continue
            world = Base.get_world_counter()
            ambig = Ref{Int32}(0)
            ms = Base._methods_by_ftype(m.sig, nothing, -1, world, true, Ref(typemin(UInt)), Ref(typemax(UInt)), ambig)::Vector
            ambig[] == 0 && continue
            for match2 in ms
                match2 = match2::Core.MethodMatch
                m2 = match2.method
                 if !(m === m2 || Base.morespecific(m2.sig, m.sig))
                    if Base.isambiguous(m, m2; ambiguous_bottom)
                        push!(ambs, sortdefs(m, m2))
                    end
                end
            end
        end
    end

Review comment (bug):
Unrelated bugfix, should be separated out into independent PR and backported to v1.10, v1.12, v1.13?

Code after:
"""
    detect_ambiguities(mod1, mod2...; recursive=false,
                                      ambiguous_bottom=false,
                                      allowed_undefineds=nothing)

Return a vector of `(Method,Method)` pairs of ambiguous methods
defined in the specified modules.
Use `recursive=true` to test in all submodules.

`ambiguous_bottom` controls whether ambiguities triggered only by
`Union{}` type parameters are included; in most cases you probably
want to set this to `false`. See [`Base.isambiguous`](@ref).

See [`Test.detect_unbound_args`](@ref) for an explanation of
`allowed_undefineds`.

!!! compat "Julia 1.8"
    `allowed_undefineds` requires at least Julia 1.8.
"""
function detect_ambiguities(mods::Module...;
                            recursive::Bool = false,
                            ambiguous_bottom::Bool = false,
                            allowed_undefineds = nothing)
    @nospecialize
    ambs = Set{Tuple{Method,Method}}()
    mods = Module[mods...]
    function sortdefs(m1::Method, m2::Method)
        ord12 = cmp(m1.file, m2.file)
        if ord12 == 0
            ord12 = cmp(m1.line, m2.line)
        end
        return ord12 <= 0 ? (m1, m2) : (m2, m1)
    end
    function examine(mt::Core.MethodTable)
        for m in Base.MethodList(mt)
            is_in_mods(parentmodule(m), recursive, mods) || continue
            world = Base.get_world_counter()
            ambig = Ref{Int32}(0)
            ms = Base._methods_by_ftype(m.sig, nothing, -1, world, true, Ref(typemin(UInt)), Ref(typemax(UInt)), ambig)::Vector
            ambig[] == 0 && continue
            for match2 in ms
                match2 = match2::Core.MethodMatch
                m2 = match2.method
                 if !(m === m2 || Base.morespecific(m2.sig, m.sig))
                    if Base.isambiguous(m, m2; ambiguous_bottom)
                        push!(ambs, sortdefs(m, m2))
                    end
                end
            end
        end
    end