JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.09k stars 5.43k forks source link

Subtype relationships not detected with certain cases of Tuple{T,T} #20130

Open TotalVerb opened 7 years ago

TotalVerb commented 7 years ago

Given

julia> immutable X{T}
       end

julia> (Tuple{T} where T <: X) <: (Tuple{X{T}} where T)
true  # as expected

julia> (Tuple{T,T} where T <: X) <: (Tuple{X{T},X{T}} where T)
false # expected true

Given

julia> immutable Y{T,U}
       end

julia> A = Tuple{T,T} where T <: Y
Tuple{T,T} where T<:Y

julia> B = Tuple{Y{T,U} where U, Y{T,U} where U} where T
Tuple{Y{T,U} where U,Y{T,U} where U} where T

julia> A <: B
false  # expected true

(the following observation was incorrect)

julia> typeintersect(A, B) == A
true   # shouldn't this imply A <: B? [ edit: never mind, my mistake ]
vtjnash commented 7 years ago
julia> (Tuple{T,T} where T <: X) <: (Tuple{X{T},X{T}} where T)
false # expected true

this is correct. Tuple{Union{}, Union{}} is a subtype of the left, but not of the right

julia> typeintersect(A, B) == A
true   # shouldn't this imply A <: B?

no, typeintersect can choose to return any type that is wider than the actual intersection. A valid answer thus is always A (even if there is no actual intersection).

TotalVerb commented 7 years ago

I am reopening this issue because seems that Tuple{Union{}, Union{}} does not invalidate the subtype relationship

julia> (Tuple{Union{},Union{}}) <: (Tuple{X{T},X{T}} where T)
true

julia> (Tuple{Union{},Union{}}) <: (Tuple{T,T} where T <: X)
true
JeffBezanson commented 7 years ago

Yes, I think we could eventually make <: return true in those cases. @vtjnash is right about typeintersect though.

andyferris commented 7 years ago

Tuple{Union{}, Union{}} is a subtype of the left, but not of the right

So... we're not going to end up with method ambiguity errors when one doesn't deal with the (im)possibility of slots being Union{} across different methods, are we?

Keno commented 7 years ago

Union{} is going to cause a whole lot of ambiguity errors. Most of the time it doesn't matter though, because you rarely ever have those as a type parameter (any you can't construct an actual instance of it). We'll need a version of detect_ambiguities that ignores these though (I have one in some PR somewhere).

tkelman commented 7 years ago

https://github.com/JuliaLang/julia/pull/20006 which needs rebasing to just be the last couple commits - we should probably change the default there, since the test that used to be verifying base was ambiguity-free is (hopefully temporarily) disabled

JeffBezanson commented 7 years ago

@andyferris No; type intersection treats Tuple{..., Union{}, ...} the same as Union{}.

andyferris commented 7 years ago

OK, thanks for the clarification (phew!)

gbaraldi commented 11 months ago

Tuple{Union{}} can no longer be constructed, so can we close this?