Removing ambiguity warnings from Julia v0.4


I’m updating the SortedSet constructors in DataStructures.jl, and I’m having trouble removing a particular ambiguity warning from Julia v0.4. The code works fine in v0.5 and v0.6 (and not just because ambiguity warnings were moved to runtime).

The warning stems from

SortedSet{O<:Ordering}(o::O, iter) = sortedset_with_eltype(o, iter, eltype(iter))
SortedSet{O<:Ordering}(iter, o::O) = sortedset_with_eltype(o, iter, eltype(iter))

This makes sense–if one calls this constructor with two Orderings, the call is ambiguous (even if this unlikely to happen).

The actual warning, however, is

WARNING: New definition
    call(Type{DataStructures.SortedSet}, Any, #O<:Base.Order.Ordering) at /Users/kevin/.julia/v0.4/DataStructures/src/sorted_set.jl:30
is ambiguous with:
    call(Type{DataStructures.SortedSet}, #O<:Base.Order.Ordering, Any) at /Users/kevin/.julia/v0.4/DataStructures/src/sorted_set.jl:29.
To fix, define
    call(Type{DataStructures.SortedSet}, _<:Any, _<:Any)
before the new definition.

The warning itself is slightly unclear (I’m pretty sure _ is a type variable), but I believe either of the following definitions should handle the actual ambiguity:

SortedSet(::Ordering,::Ordering) = throw(ArgumentError("SortedSet with two parameters must be called with an Ordering and an interable"))
SortedSet{T}(::T,::T) = throw(ArgumentError("SortedSet with two parameters must be called with an Ordering and an interable"))

Unfortunately, neither does. Am I missing something, or is this an issue with the parser in v0.4?

With v0.6 around the corner, this arguably isn’t that important. But there’s a desire to continue to support DataStructures.jl on v0.4, so it would be nice not to introduce this warning.

Any thoughts welcome!



This won’t. It’ll just introduce more ambiguity. The other one is probably a bug in the type system.


Thanks, @yuyichao.

I was able to get around it by removing the O<:Ordering parameterization and just using Ordering directly in the signature:

SortedSet(o::Ordering, iter) = sortedset_with_eltype(o, iter, eltype(iter))
SortedSet(iter, o::Ordering) = sortedset_with_eltype(o, iter, eltype(iter))

In the original definition, O wasn’t used, so it absolutely didn’t need to be there. A second set of similar definitions did use the parameterization, but it wasn’t to hard to change the definition not to use it.