Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False ambiguity with supertype dispatch #20567

Closed
timholy opened this issue Feb 11, 2017 · 2 comments
Closed

False ambiguity with supertype dispatch #20567

timholy opened this issue Feb 11, 2017 · 2 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@timholy
Copy link
Member

timholy commented Feb 11, 2017

The following claims an ambiguity, and while there's a workaround it seems like it shouldn't be necessary:

module Amb

abstract type FixedPoint{T <: Integer, f} <: Real end
struct Normed{T<:Unsigned,f} <: FixedPoint{T,f}
    i::T
end
struct Fixed{T <: Signed,f} <: FixedPoint{T,  f}
    i::T
end

# typealias ShortInts Union{Int8,UInt8,Int16,UInt16}
typealias ShortInts Int8

floattype{T<:ShortInts,f}(::Type{FixedPoint{T,f}}) = Float32
floattype{T,f}(::Type{FixedPoint{T,f}}) = Float64

floattype{F<:FixedPoint}(::Type{F}) = floattype(supertype(F))
# The following doesn't exhibit the ambiguity, but seems unnecessarily awkward
# floattype{T,f,F<:FixedPoint{T,f}}(::Type{F}) = floattype(supertype(T))

end

The commented-out version does not trigger ambiguity detection.

julia> using Base.Test

julia> include("/tmp/false_ambiguity.jl")
Amb

julia> setdiff(detect_ambiguities(Amb, Base, Core),
               detect_ambiguities(Base, Core))
Skipping Base.<|
Skipping Base.<|
1-element Array{Tuple{Method,Method},1}:
 (floattype(::Type{Amb.FixedPoint{T,f}}) where {T, f} in Amb at /tmp/false_ambiguity.jl:15, floattype(::Type{F}) where F<:Amb.FixedPoint in Amb at /tmp/false_ambiguity.jl:17)

julia> Amb.floattype(Amb.Normed{UInt8,5})
ERROR: MethodError: Amb.floattype(::Type{Amb.FixedPoint{UInt8,5}}) is ambiguous. Candidates:
  floattype(::Type{F}) where F<:Amb.FixedPoint in Amb at /tmp/false_ambiguity.jl:17
  floattype(::Type{Amb.FixedPoint{T,f}}) where {T, f} in Amb at /tmp/false_ambiguity.jl:15
Stacktrace:
 [1] floattype(::Type{Amb.Normed{UInt8,5}}) at /tmp/false_ambiguity.jl:17

Some alternative definitions also trigger ambiguity detection:

# Also ambiguous:
floattype{T<:Fixed}(::Type{T}) = floattype(supertype(T))
floattype{T<:Normed}(::Type{T}) = floattype(supertype(T))

Example take from FixedPointNumbers.

@timholy timholy added the types and dispatch Types, subtyping and method dispatch label Feb 11, 2017
@yuyichao
Copy link
Contributor

The first case is dup of #11597 (comment) you can workaround it by adding T<:Integer to the first method.

The second case is dup of #20246

@timholy
Copy link
Member Author

timholy commented Feb 11, 2017

I'll close then. Thanks for the workaround!

@timholy timholy closed this as completed Feb 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

2 participants