diff --git a/doc/src/manual/methods.md b/doc/src/manual/methods.md index eb03c6190828f..6ee576cb45332 100644 --- a/doc/src/manual/methods.md +++ b/doc/src/manual/methods.md @@ -252,8 +252,8 @@ julia> g(2, 3.0) julia> g(2.0, 3.0) ERROR: MethodError: g(::Float64, ::Float64) is ambiguous. Candidates: - g(x, y::Float64) in Main at none:1 g(x::Float64, y) in Main at none:1 + g(x, y::Float64) in Main at none:1 Possible fix, define g(::Float64, ::Float64) ``` diff --git a/src/gf.c b/src/gf.c index ba223296d7302..fb1fc392416e4 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2815,10 +2815,20 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs, int subt2 = matc2->fully_covers != NOT_FULLY_COVERS; if (!subt2 && subt) break; - if (subt == subt2) - if (subt || !jl_has_empty_intersection(m->sig, m2->sig)) - if (!jl_type_morespecific((jl_value_t*)m->sig, (jl_value_t*)m2->sig)) + if (subt == subt2) { + if (lim >= 0) { + if (subt || !jl_has_empty_intersection(m->sig, m2->sig)) + if (!jl_type_morespecific((jl_value_t*)m->sig, (jl_value_t*)m2->sig)) + break; + } + else { + // if unlimited, use approximate sorting, with the only + // main downside being that it may be overly- + // conservative at reporting existence of ambiguities + if (jl_type_morespecific((jl_value_t*)m2->sig, (jl_value_t*)m->sig)) break; + } + } jl_array_ptr_set(env.t, i - j, matc2); } jl_array_ptr_set(env.t, i - j, env.matc); diff --git a/test/errorshow.jl b/test/errorshow.jl index 047e34bad69f6..4236e7388317b 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -86,7 +86,7 @@ method_c2(x::Int32, y::Int32, z::Int32) = true method_c2(x::T, y::T, z::T) where {T<:Real} = true Base.show_method_candidates(buf, Base.MethodError(method_c2,(1., 1., 2))) -@test String(take!(buf)) == "\nClosest candidates are:\n method_c2(!Matched::Int32, ::Float64, ::Any...)$cfile$(c2line+2)\n method_c2(::T, ::T, !Matched::T) where T<:Real$cfile$(c2line+5)\n method_c2(!Matched::Int32, ::Any...)$cfile$(c2line+1)\n ..." +@test String(take!(buf)) == "\nClosest candidates are:\n method_c2(!Matched::Int32, ::Float64, ::Any...)$cfile$(c2line+2)\n method_c2(!Matched::Int32, ::Any...)$cfile$(c2line+1)\n method_c2(::T, ::T, !Matched::T) where T<:Real$cfile$(c2line+5)\n ..." c3line = @__LINE__() + 1 method_c3(x::Float64, y::Float64) = true @@ -124,7 +124,7 @@ PR16155line2 = @__LINE__() + 1 (::Type{T})(arg::Any) where {T<:PR16155} = "replace call-to-convert method from sysimg" Base.show_method_candidates(buf, MethodError(PR16155,(1.0, 2.0, Int64(3)))) -@test String(take!(buf)) == "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n (::Type{T})(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2\n $(curmod_prefix)PR16155(!Matched::Int64, ::Any)$cfile$PR16155line" +@test String(take!(buf)) == "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(!Matched::Int64, ::Any)$cfile$PR16155line\n (::Type{T})(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2" Base.show_method_candidates(buf, MethodError(PR16155,(Int64(3), 2.0, Int64(3)))) @test String(take!(buf)) == "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n (::Type{T})(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2"