Julia: Subtyping bug: incorrect interaction between variables with degenerate bounds and diagonal rule

Created on 3 Sep 2019  Â·  4Comments  Â·  Source: JuliaLang/julia

This does not hold in Julia 1.2.0, but I expect that it should hold:

julia> Vector{Vector{Tuple{T,T}} where Int<:T<:Int} <:
       Vector{Vector{Tuple{S1,S1} where S<:S1<:S}} where S
false

Version info:

Julia Version 1.2.0
Commit c6da87ff4b (2019-08-20 00:03 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
types and dispatch

Most helpful comment

@rafaqz I believe Vector{<:t} is equivalent to Vector{T} where T<:t and not Vector{T<:t}. For example:

julia> Vector{<:Int} == Vector{X} where X<:Int
true

julia> Vector{<:Int} == Vector{Int}
false

Therefore, it is ok that with your Vector{<:...}-type the result is different.

Still, the original example should hold. If we directly use S instead of S1 where S<:S1<:S, which is an equivalent type, subtyping holds as it should:

julia> ta = Vector{Vector{Tuple{T,T}} where Int<:T<:Int}
Array{Array{Tuple{T,T},1} where Int64<:T<:Int64,1}

julia> tb1 = Vector{Vector{Tuple{S1,S1} where S<:S1<:S}} where S
Array{Array{Tuple{S1,S1} where S<:S1<:S,1},1} where S

julia> tb2 = Vector{Vector{Tuple{S,S}}} where S
Array{Array{Tuple{S,S},1},1} where S

julia> tb1 == tb2
true

julia> ta <: tb1
false

julia> ta <: tb2
true

Also, (to elaborate on the title) with a single-element tuple, or otherwise non-diagonal S1, subtyping is correct:

julia> Vector{Vector{Tuple{T}} where Int<:T<:Int} <:
       Vector{Vector{Tuple{S1} where S<:S1<:S}} where S
true

julia> Vector{Vector{Tuple{T, Ref{T}}} where Int<:T<:Int} <:
       Vector{Vector{Tuple{S1, Ref{S1}} where S<:S1<:S}} where S
true

All 4 comments

julia> Vector{Vector{Tuple{T,T}} where Int<:T<:Int} <:
              Vector{<:Vector{Tuple{S1,S1} where S<:S1<:S}} where S
true

@rafaqz what version are you in?

Still 1.1.0. But that shouldn't change this kind of subtyping or we are in trouble...

My version has an extra <: in it in the second type, that was my less-than-clear point. You need <: when the type is ultimately parametric. But I'm interested in why that is.

@rafaqz I believe Vector{<:t} is equivalent to Vector{T} where T<:t and not Vector{T<:t}. For example:

julia> Vector{<:Int} == Vector{X} where X<:Int
true

julia> Vector{<:Int} == Vector{Int}
false

Therefore, it is ok that with your Vector{<:...}-type the result is different.

Still, the original example should hold. If we directly use S instead of S1 where S<:S1<:S, which is an equivalent type, subtyping holds as it should:

julia> ta = Vector{Vector{Tuple{T,T}} where Int<:T<:Int}
Array{Array{Tuple{T,T},1} where Int64<:T<:Int64,1}

julia> tb1 = Vector{Vector{Tuple{S1,S1} where S<:S1<:S}} where S
Array{Array{Tuple{S1,S1} where S<:S1<:S,1},1} where S

julia> tb2 = Vector{Vector{Tuple{S,S}}} where S
Array{Array{Tuple{S,S},1},1} where S

julia> tb1 == tb2
true

julia> ta <: tb1
false

julia> ta <: tb2
true

Also, (to elaborate on the title) with a single-element tuple, or otherwise non-diagonal S1, subtyping is correct:

julia> Vector{Vector{Tuple{T}} where Int<:T<:Int} <:
       Vector{Vector{Tuple{S1} where S<:S1<:S}} where S
true

julia> Vector{Vector{Tuple{T, Ref{T}}} where Int<:T<:Int} <:
       Vector{Vector{Tuple{S1, Ref{S1}} where S<:S1<:S}} where S
true
Was this page helpful?
0 / 5 - 0 ratings

Related issues

omus picture omus  Â·  3Comments

tkoolen picture tkoolen  Â·  3Comments

StefanKarpinski picture StefanKarpinski  Â·  3Comments

iamed2 picture iamed2  Â·  3Comments

musm picture musm  Â·  3Comments