@@ -941,13 +941,41 @@ function method_exists(f::ANY, t::ANY)
941
941
typemax (UInt)) != 0
942
942
end
943
943
944
+ """
945
+ isambiguous(m1, m2, [allow_bottom_tparams=true]) -> Bool
946
+
947
+ Determine whether two methods `m1` and `m2` (typically of the same
948
+ function) are ambiguous. This test is performed in the context of
949
+ other methods of the same function; in isolation, `m1` and `m2` might
950
+ be ambiguous, but if a third method resolving the ambiguity has been
951
+ defined, this returns `false`.
952
+
953
+ For parametric types, `allow_bottom_tparams` controls whether
954
+ `Union{}` is considered a valid intersection of type parameters. For example:
955
+ ```jldoctest
956
+ julia> foo(x::Complex{<:Integer}) = 1
957
+ foo (generic function with 1 method)
958
+
959
+ julia> foo(x::Complex{<:Rational}) = 2
960
+ foo (generic function with 2 methods)
961
+
962
+ julia> m1, m2 = collect(methods(foo));
963
+
964
+ julia> typeintersect(m1.sig, m2.sig)
965
+ Tuple{#foo,Complex{Union{}}}
966
+
967
+ julia> Base.isambiguous(m1, m2, true)
968
+ true
969
+
970
+ julia> Base.isambiguous(m1, m2, false)
971
+ false
972
+ ```
973
+ """
944
974
function isambiguous (m1:: Method , m2:: Method , allow_bottom_tparams:: Bool = true )
945
975
ti = typeintersect (m1. sig, m2. sig)
946
976
ti === Bottom && return false
947
977
if ! allow_bottom_tparams
948
- (_, env) = ccall (:jl_match_method , Ref{SimpleVector}, (Any, Any),
949
- ti, m1. sig)
950
- any (x-> x === Bottom, env) && return false
978
+ has_bottom_parameter (ti) && return false
951
979
end
952
980
ml = _methods_by_ftype (ti, - 1 , typemax (UInt))
953
981
isempty (ml) && return true
@@ -959,6 +987,23 @@ function isambiguous(m1::Method, m2::Method, allow_bottom_tparams::Bool=true)
959
987
return true
960
988
end
961
989
990
+ """
991
+ has_bottom_parameter(t) -> Bool
992
+
993
+ Determine whether `t` is a Type for which one or more of its parameters is `Union{}`.
994
+ """
995
+ function has_bottom_parameter (t:: Type )
996
+ ret = false
997
+ for p in t. parameters
998
+ ret |= (p == Bottom) || has_bottom_parameter (p)
999
+ end
1000
+ ret
1001
+ end
1002
+ has_bottom_parameter (t:: UnionAll ) = has_bottom_parameter (unwrap_unionall (t))
1003
+ has_bottom_parameter (t:: Union ) = has_bottom_parameter (t. a) & has_bottom_parameter (t. b)
1004
+ has_bottom_parameter (t:: TypeVar ) = has_bottom_parameter (t. ub)
1005
+ has_bottom_parameter (:: Any ) = false
1006
+
962
1007
min_world (m:: Method ) = reinterpret (UInt, m. min_world)
963
1008
max_world (m:: Method ) = reinterpret (UInt, m. max_world)
964
1009
min_world (m:: Core.MethodInstance ) = reinterpret (UInt, m. min_world)
0 commit comments