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

incorrect dispatch for Tuple{Vararg} type? #22485

Closed
stevengj opened this issue Jun 23, 2017 · 5 comments
Closed

incorrect dispatch for Tuple{Vararg} type? #22485

stevengj opened this issue Jun 23, 2017 · 5 comments
Assignees
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@stevengj
Copy link
Member

stevengj commented Jun 23, 2017

In both Julia 0.5 and 0.6, I get

julia> f{T<:Tuple}(::Type{T}) = 1;
       f{T}(::Type{Tuple{Vararg{T}}}) = 2;
       f{T,N}(::Type{Tuple{Vararg{T,N}}}) = 3
f (generic function with 3 methods)

julia> f(Tuple{Vararg{Any}})
1

when I would have expected 2. Isn't the ::Type{Tuple{Vararg{T}}} more specific here?

@stevengj stevengj added the types and dispatch Types, subtyping and method dispatch label Jun 23, 2017
@martinholters
Copy link
Member

julia> Tuple{Vararg{Any}} isa (Type{Tuple{Vararg{T}}} where T)
false

OTOH:

julia> Tuple{Vararg{Int}} isa (Type{Tuple{Vararg{T}}} where T)
true

julia> f(Tuple{Vararg{Int}})
2

I don't know whether it makes sense to restrict the matched type to concrete ones there, but this definitely looks wrong:

julia> T1 = Type{Tuple{Vararg{Any}}};

julia> T2 = Type{Tuple{Vararg{T}}} where Any<:T<:Any;

julia> T3 = Type{Tuple{Vararg{T}}} where T<:Any;

julia> T1 == T2
true

julia> T2 <: T3
true

julia> T1 <: T3
false

@JeffBezanson JeffBezanson self-assigned this Sep 19, 2017
@JeffBezanson
Copy link
Member

T2 <: T3 is now also false, likely due to the fix for #24166.

@NHDaly
Copy link
Member

NHDaly commented Jan 8, 2019

This was closed, but was the original question ever answered? I still get the surprising dispatch behavior on julia 1.0:

julia> begin
         f(::Type{T})  where T<:Tuple = 1
         f(::Type{Tuple{Vararg{T}}}) where T = 2
         f(::Type{Tuple{Vararg{T,N}}}) where {T,N} = 3
       end
>> f (generic function with 5 methods)

julia> f(Tuple{Vararg{Any}})
>> 1

@NHDaly
Copy link
Member

NHDaly commented Jan 8, 2019

And this related, surprising behavior:

julia> g(::Type{Tuple{Vararg{T}}}) where T = @show T
       g(Tuple{Int,Int,Int})
ERROR: MethodError: no method matching g(::Type{Tuple{Int64,Int64,Int64}})
Closest candidates are:
  g(::Type{Tuple{Vararg{T,N} where N}}) where T at REPL[22]:1
Stacktrace:
 [1] top-level scope at none:0

julia> g(::Type{Tuple{Vararg{T,N}}}) where {T,N} = @show (T,N)
       g(Tuple{Int,Int,Int})
(T, N) = (Int64, 3)
>> (Int64, 3)

And one more surprise:

julia> h(::Type{Tuple{Vararg{Any,N}}}) where {N} = @show (N)
       h(Tuple{Int,Int,Int})
ERROR: MethodError: no method matching h(::Type{Tuple{Int64,Int64,Int64}})
Closest candidates are:
  h(::Type{Tuple{Vararg{Any,N}}}) where N at REPL[24]:1

EDIT: although maybe that last one isn't surprising, because it seems like it's a requirement that all the args in the Vararg be of the same concrete type.

@JeffBezanson
Copy link
Member

Yes, these are because of the diagonal rule and the nesting order of Type{...} and where N.

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

4 participants