Removing ambiguity warnings from Julia v0.4


#1

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!

Cheers,
Kevin


#2

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


#3

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.

Cheers,
Kevin