Closed
Description
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.