Method ambiguities are cases where multiple methods are applicable to a given set of arguments, without having a most specific method.


One easy example is the following:

julia> f(x::Int, y::Integer) = 1f (generic function with 1 method)
julia> f(x::Integer, y::Int) = 2f (generic function with 2 methods)
julia> println(f(1, 2))ERROR: MethodError: f(::Int64, ::Int64) is ambiguous. Candidates: f(x::Integer, y::Int64) @ Main REPL[2]:1 f(x::Int64, y::Integer) @ Main REPL[1]:1 Possible fix, define f(::Int64, ::Int64)

This will throw an MethodError because both methods are equally specific. The solution is to add a third method:

f(x::Int, y::Int) = ? # `?` is dependent on the use case, most times it will be `1` or `2`

Test function

test_ambiguities(package::Union{Module, PkgId})
test_ambiguities(packages::Vector{Union{Module, PkgId}})

Test that there is no method ambiguities in given package(s). It calls Test.detect_ambiguities in a separated clean process to avoid false-positives.

Keyword Arguments

  • broken::Bool = false: If true, it uses @test_broken instead of @test and shortens the error message.
  • color::Union{Bool, Nothing} = nothing: Enable/disable colorful output if a Bool. nothing (default) means to inherit the setting in the current process.
  • exclude::AbstractVector = []: A vector of functions or types to be excluded from ambiguity testing. A function means to exclude all its methods. A type means to exclude all its methods of the callable (sometimes also called "functor") and the constructor. That is to say, MyModule.MyType means to ignore ambiguities between (::MyType)(x, y::Int) and (::MyType)(x::Int, y).
  • recursive::Bool = true: Passed to Test.detect_ambiguities. Note that the default here (true) is different from detect_ambiguities. This is for testing ambiguities in methods defined in all sub-modules.
  • Other keyword arguments such as imported and ambiguous_bottom are passed to Test.detect_ambiguities as-is.