-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
confusing dispatch when method parameter bounds are wider than a type parameter's declared bounds #6383
Comments
This seems more serious than just a spurious ambiguity warning. It can manifest itself as a method sorting bug. Here's a simpler example: julia> type Foo{A<:Real}; end
julia> f{A}(x::Foo{A}) = 1
f (generic function with 1 method)
julia> f(x::Foo, y...) = 2
f (generic function with 2 methods)
julia> f(Foo{Int}())
2 If Foo is changed such that |
Should be taken care of by jb/subtypes. But not as much of an issue now that we don't print ambiguity warnings early |
My comment from #23823:
The second method's 1-arg form appears (unless you're an Expert) as if it is less specific than the first. However, Foo is treated as Foo{T} where T<:Real, while the compiler puts a type bound of Any on A. I think it would make sense if Foo{A} where A was treated as Foo{A} where A<:Real, at least in method definitions. |
Easy test cases in #25361. |
Still an issue: abstract type StaticArray{S <: Tuple, T, N} <: AbstractArray{T, N} end
# Like `getindex` but with short method tables
gtindex(a::StaticArray{<:Any,<:Any,N}, inds::Vararg{Int,N}) where N = 1
gtindex(a::StaticArray, inds::Union{Int, StaticArray{<:Any, Int}, Colon}...) = 2
julia> methods(gtindex)
# 2 methods for generic function "gtindex":
[1] gtindex(a::StaticArray, inds::Union{Colon, Int64, StaticArray{#s4,Int64,N} where N where #s4}...) in Main at /tmp/tim/dispatch.jl:5
[2] gtindex(a::StaticArray{#s3,#s4,N} where #s4 where #s3, inds::Vararg{Int64,N}) where N in Main at /tmp/tim/dispatch.jl:4 This is wrong, since the method returning If I change the first to gtindex(a::StaticArray{<:Tuple,<:Any,N}, inds::Vararg{Int,N}) where N = 1 then the sorting is correct. |
Is there any progress on this? If there is no fix in the pipeline, we should at least add a section in the documentation for "Types" to make this quirk explicitly known. As a computer scientist and fairly recent newcomer to Julia, this issue was very confusing and surprising to discover by accident... |
This does relate to a similar aesthetic issue I have noticed, namely that the current requirements for inner constructors create redundancy in many, if not most, scenarios: struct Foo{A<:AbstractArray}
data::A
Foo(data::A) where {A<:AbstractArray} = new{A}(data)
end Now of course, given that this bug still exists, we actually have to remove the bound from Foo's generic type argument to avoid erroneous dispatch. This inadvertently solves the redundancy issue but comes at the cost of code clarity (in my opinion, at least) because one cannot tell from the signature of This begs the question: why aren't type arguments visible to inner-constructors? I think I saw this discussed somewhere else at some point, and I assume there is some technical limitation, but it would be nice if the compiler could, by default, assume that the type constraints on |
Hmm, I actually can't reproduce the original example with current (1.8.3) syntax
I won't close the issue just yet in case I am misunderstanding, but this all looks like it's working properly now as far as I can tell |
See a85476b and 005197a and comments therein.
In summary, dispatch on a parametric type whose type is restricted in the declaration (
type A{T<:Integer}
etc.) make a difference betweenA
,A{T}
andA{T<:Integer}
. In one case,A{T}
seems to be taken as more general thanA
; in another case,A
seems to be taken as more general thanA{T<:Integer}
- see examples below.Example: this shows the ambiguity
Currently, the workarounds for the example above are: defining the disambiguation method with an otherwise useless parameter
Or restricting the first method to
S<:Integer
:One more problem: from the last example, continue like this:
Again, to fix it restrict the type parameter in the above definition:
The text was updated successfully, but these errors were encountered: