Skip to content

Commit

Permalink
Ambiguity test that ignores matches due to Union{} tparams
Browse files Browse the repository at this point in the history
Because of the way methods are specified, there is often spurious
ambiguities due to a type parameter being able to take the value
Union{}, (e.g. Type{T} becomes Type{Union{}}). Since detect_ambiguities
reports these, it can drown out more serious ambiguities among
non-Union{} types. Add a keyword argument to detect_ambiguities,
that ignores all ambiguities that only occur if one of the type
parameters has to be Union{}.
  • Loading branch information
Keno committed Feb 1, 2017
1 parent 7786ff5 commit e101000
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
7 changes: 6 additions & 1 deletion base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -850,9 +850,14 @@ function method_exists(f::ANY, t::ANY)
typemax(UInt)) != 0
end

function isambiguous(m1::Method, m2::Method)
function isambiguous(m1::Method, m2::Method, allow_bottom_tparams::Bool=true)
ti = typeintersect(m1.sig, m2.sig)
ti === Bottom && return false
if !allow_bottom_tparams
(_, env) = ccall(:jl_match_method, Ref{SimpleVector}, (Any, Any),
ti, m1.sig)
any(x->x === Bottom, env) && return false
end
ml = _methods_by_ftype(ti, -1, typemax(UInt))
isempty(ml) && return true
for m in ml
Expand Down
4 changes: 2 additions & 2 deletions base/test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ defined in the specified modules. Use `imported=true` if you wish to
also test functions that were imported into these modules from
elsewhere.
"""
function detect_ambiguities(mods...; imported::Bool=false)
function detect_ambiguities(mods...; imported::Bool=false, allow_bottom::Bool=true)
function sortdefs(m1, m2)
ord12 = m1.file < m2.file
if !ord12 && (m1.file == m2.file)
Expand All @@ -1145,7 +1145,7 @@ function detect_ambiguities(mods...; imported::Bool=false)
for m in mt
if m.ambig !== nothing
for m2 in m.ambig
if Base.isambiguous(m, m2)
if Base.isambiguous(m, m2, allow_bottom)
push!(ambs, sortdefs(m, m2))
end
end
Expand Down

0 comments on commit e101000

Please sign in to comment.