/
githubmirror
/
julia
Обзор
Документация
Войти
/
githubmirror
/
julia
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/subtype.jl
3 528 строк
158 KB
Keno Fischer
type system: Make `Type{T}` subtyping sound with respect to `==` (#62263)
06 июл 2026, 03:58
Не верифицирован
06 июл 2026, 03:58
6604df4
Код
Авторство
О чём код?
# This file is a part of Julia. License is MIT: https://julialang.org/license using Base: Bottom using Test using LinearAlgebra macro UnionAll(var, expr) Expr(:where, esc(expr), esc(var)) end const issub = (<:) issub_strict(@nospecialize(x),@nospecialize(y)) = issub(x,y) && !issub(y,x) isequal_type(@nospecialize(x),@nospecialize(y)) = issub(x,y) && issub(y,x) notequal_type(@nospecialize(x),@nospecialize(y)) = !isequal_type(x, y) _type_intersect(@nospecialize(x), @nospecialize(y)) = ccall(:jl_intersect_types, Any, (Any, Any), x, y) intersection_env(@nospecialize(x), @nospecialize(y)) = Core.svec(Base.typeintersect_env(x, y)...) # level 1: no varargs, union, UnionAll function test_1() @test issub_strict(Int, Integer) @test issub_strict(Vector{Int}, AbstractVector{Int}) @test isequal_type(Int, Int) @test isequal_type(Integer, Integer) @test isequal_type(Vector{Int}, Vector{Int}) @test isequal_type(AbstractVector{Int}, AbstractVector{Int}) @test issub_strict(Tuple{Int,Int}, Tuple{Integer,Integer}) @test issub_strict(Tuple{Vector{Int}}, Tuple{AbstractVector{Int}}) @test isequal_type(Tuple{Integer,Integer}, Tuple{Integer,Integer}) @test !issub(Tuple{Int,Int}, Tuple{Int}) @test !issub(Tuple{Int}, Tuple{Integer,Integer}) @test !issub(Vector{Int}, Vector{Integer}) end # level 2: varargs function test_2() @test issub_strict(Tuple{Int,Int}, Tuple{Vararg{Int}}) @test issub_strict(Tuple{Int,Int}, Tuple{Int,Vararg{Int}}) @test issub_strict(Tuple{Int,Int}, Tuple{Int,Vararg{Integer}}) @test issub_strict(Tuple{Int,Int}, Tuple{Int,Int,Vararg{Integer}}) @test issub_strict(Tuple{Int,Vararg{Int}}, Tuple{Vararg{Int}}) @test issub_strict(Tuple{Int,Int,Int}, Tuple{Vararg{Int}}) @test issub_strict(Tuple{Int,Int,Int}, Tuple{Integer,Vararg{Int}}) @test issub_strict(Tuple{Int}, Tuple{Any}) @test issub_strict(Tuple{}, Tuple{Vararg{Any}}) @test isequal_type(Tuple{Int}, Tuple{Int}) @test isequal_type(Tuple{Vararg{Integer}}, Tuple{Vararg{Integer}}) @test !issub(Tuple{}, Tuple{Int, Vararg{Int}}) @test !issub(Tuple{Int}, Tuple{Int, Int, Vararg{Int}}) @test !issub(Tuple{Int, Tuple{Real, Integer}}, Tuple{Vararg{Int}}) @test isequal_type(Tuple{Int,Int}, Tuple{Vararg{Int,2}}) @test Tuple{Int,Vararg{Int,2}} == Tuple{Int,Int,Int} @test Tuple{Int,Vararg{Int,2}} === Tuple{Int,Int,Int} @test Tuple{Any, Any} === Tuple{Vararg{Any,2}} @test Tuple{Int,Vararg{Int,2}} == Tuple{Int,Int,Vararg{Int,1}} @test Tuple{Int,Vararg{Int,2}} == Tuple{Int,Int,Int,Vararg{Int,0}} @test !(Tuple{Int,Vararg{Int,2}} <: Tuple{Int,Int,Int,Vararg{Int,1}}) @test Tuple{Int,Vararg{Int}} == Tuple{Int,Vararg{Int}} @test (@UnionAll N Tuple{Int,Vararg{Int,N}}) == (@UnionAll N Tuple{Int,Vararg{Int,N}}) @test Union{Tuple{}, Tuple{Int}, Tuple{UInt}} <: Union{ Tuple{}, Tuple{Int}, Tuple{UInt}, Tuple{UInt, Vararg{UInt}}, Tuple{Int, Int, Vararg{Int}} } @test issub_strict(Tuple{Tuple{Int,Int},Tuple{Int,Int}}, Tuple{NTuple{N,Int},NTuple{N,Int}} where N) @test !issub(Tuple{Tuple{Int,Int},Tuple{Int,}}, Tuple{NTuple{N,Int},NTuple{N,Int}} where N) @test NTuple{0} === Tuple{} @test !issub(Tuple{Val{3}, Vararg{Val{3}}}, Tuple{Vararg{Val{N}, N}} where N) @test issub_strict(Tuple{Int,Int}, Tuple{Int,Int,Vararg{Int,N}} where N) @test issub_strict(Tuple{Int,Int}, Tuple{E,E,Vararg{E,N}} where E where N) @test issub(Type{Tuple{VecElement{Bool}}}, (Type{Tuple{Vararg{VecElement{T},N}}} where T where N)) @test isequal_type(Type{Tuple{Vararg{Int,N}} where N}, Type{Tuple{Vararg{Int}}}) @test Type{Tuple{Vararg{Int,N}} where N} !== Type{Tuple{Vararg{Int}}} end function test_diagonal() @test !issub(Tuple{Integer,Integer}, @UnionAll T Tuple{T,T}) @test issub(Tuple{Integer,Int}, (@UnionAll T @UnionAll S<:T Tuple{T,S})) @test issub(Tuple{Integer,Int}, (@UnionAll T @UnionAll T<:S<:T Tuple{T,S})) @test issub(Tuple{Integer,Int,Int}, (@UnionAll T @UnionAll T<:S<:T Tuple{T,S,S})) @test issub_strict((@UnionAll R Tuple{R,R}), (@UnionAll T @UnionAll S Tuple{T,S})) @test issub_strict((@UnionAll R Tuple{R,R}), (@UnionAll T @UnionAll S<:T Tuple{T,S})) @test issub_strict((@UnionAll R Tuple{R,R}), (@UnionAll T @UnionAll T<:S<:T Tuple{T,S})) @test issub_strict((@UnionAll R Tuple{R,R}), (@UnionAll T @UnionAll S>:T Tuple{T,S})) @test !issub(Tuple{Real,Real}, @UnionAll T<:Real Tuple{T,T}) @test issub((@UnionAll S<:Int (@UnionAll R<:AbstractString Tuple{S,R,Vector{Any}})), (@UnionAll T Tuple{T, T, Vector{T}})) @test issub_strict(Tuple{String, Real, Ref{Number}}, (@UnionAll T Tuple{Union{T,String}, T, Ref{T}})) @test issub_strict(Tuple{String, Real}, (@UnionAll T Tuple{Union{T,String}, T})) @test !issub( Tuple{Real, Real}, (@UnionAll T Tuple{Union{T,String}, T})) @test issub_strict(Tuple{Int, Int}, (@UnionAll T Tuple{Union{T,String}, T})) # Diagonal counter is scoped per consistency check, so occurrences of T in # a typevar bound do not combine with occurrences in the outer body. # `Tuple{S, T} where S<:Tuple{T} where T` is no longer diagonal in T: @test issub(Tuple{Tuple{String}, Int}, Tuple{S, T} where {T, S<:Tuple{T}}) @test issub(Tuple{Tuple{Int}, Int}, Tuple{S, T} where {T, S<:Tuple{T}}) # ...but `Tuple{S, T} where S<:Tuple{T, T}` still is — both T occurrences # are in the same Tuple{} frame inside the consistency check. @test !issub(Tuple{Tuple{Int, Int}, String}, Tuple{S, T} where {T, S<:Tuple{T, T}}) @test issub(Tuple{Tuple{Int, Int}, Int}, Tuple{S, T} where {T, S<:Tuple{T, T}}) # don't consider a diagonal variable concrete if it already has an abstract lower bound @test isequal_type(Tuple{Vararg{A}} where A>:Integer, Tuple{Vararg{A}} where A>:Integer) # issue #24166 @test !issub(Tuple{T, T, Ref{T}} where T, Tuple{S, S, Ref{Q} where Q} where S) @test !issub(Tuple{T, T, Ref{T}} where T, Tuple{S, S, Ref{Q} where Q} where S<:Integer) @test !issub(Tuple{T, T, Ref{T}} where T, Tuple{S, S, Ref{Q} where Q} where S<:Int) @test issub(Tuple{T, T, Ref{T}} where T<:Int, Tuple{S, S, Ref{Q} where Q} where S) @test !issub(Tuple{T, T, Ref{T}} where T>:Int, Tuple{S, S, Ref{Q} where Q} where S) @test !issub(Tuple{T, T, Ref{T}} where T>:Integer, Tuple{S, S, Ref{Q} where Q} where S) @test !issub(Tuple{T, T, Ref{T}} where T>:Any, Tuple{S, S, Ref{Q} where Q} where S) @test issub(Tuple{T, T} where Int<:T<:Int, Tuple{T, T} where Int<:T<:Int) @test issub(Tuple{T, T} where T>:Int, Tuple{T, T} where T>:Int) @test issub(Tuple{Tuple{T, T} where T>:Int}, Tuple{Tuple{T, T} where T>:Int}) @test issub(Tuple{Tuple{T, T} where T>:Int}, Tuple{Tuple{T, T}} where T>:Int) @test issub(Tuple{Tuple{T, T}} where T>:Int, Tuple{Tuple{T, T} where T>:Int}) @test issub(Vector{Tuple{T, T} where Number<:T<:Number}, Vector{Tuple{Number, Number}}) @test issub(Type{Tuple{T,Any} where T}, Type{Tuple{T,T}} where T) @test !issub(Type{Tuple{T,Any,T} where T}, Type{Tuple{T,T,T}} where T) @test issub(Type{Tuple{T} where T}, Type{Tuple{T}} where T) @test issub(Ref{Tuple{T} where T}, Ref{Tuple{T}} where T) @test !issub(Type{Tuple{T,T} where T}, Type{Tuple{T,T}} where T) @test !issub(Type{Tuple{T,T,T} where T}, Type{Tuple{T,T,T}} where T) @test isequal_type(Ref{Tuple{T, T} where Int<:T<:Int}, Ref{Tuple{S, S}} where Int<:S<:Int) # issue #53021 @test Tuple{X, X} where {X<:Union{}} <: Tuple{X, X, Vararg{Any}} where {Int<:X<:Int} @test Tuple{Integer, X, Vararg{X}} where {X<:Int} <: Tuple{Any, Vararg{X}} where {X>:Int} @test Tuple{Any, X, Vararg{X}} where {X<:Int} <: Tuple{Vararg{X}} where X>:Integer @test Tuple{Integer, Integer, Any, Vararg{Any}} <: Tuple{Vararg{X}} where X>:Integer # issue #53019 @test Tuple{T,T} where {T<:Int} <: Tuple{T,T} where {T>:Int} let A = Tuple{Int,Int8,Vector{Integer}}, B = Tuple{T,T,Vector{T}} where T>:Integer, C = Tuple{T,T,Vector{Union{Integer,T}}} where T @test A <: B @test B == C @test A <: C @test Tuple{Int,Int8,Vector{Any}} <: C end # #26108 @test !issub((Tuple{T, T, Vector{T}} where T), Tuple{T, T, Any} where T) # #26716 @test !issub((Union{Tuple{Int,Bool}, Tuple{P,Bool}} where P), Tuple{Union{T,Int}, T} where T) @test issub_strict(Tuple{Ref{Tuple{N,N}}, Ref{N}} where N, Tuple{Ref{Tuple{N1,N1}}, Ref{N2}} where {N1, N2}) @test !issub(Tuple{Type{Tuple{Vararg{T}} where T <: Integer}, Tuple{Float64, Int}}, Tuple{Type{Tuple{Vararg{T}}}, Tuple{Vararg{T}}} where T) # non-types @test issub_strict(Tuple{3,3}, NTuple) @test !issub(Tuple{3,4}, NTuple) end # level 3: UnionAll function test_3() @test issub_strict(Vector{Int}, @UnionAll T Vector{T}) @test issub_strict((@UnionAll T Pair{T,T}), Pair) @test issub(Pair{Int,Int8}, Pair) @test issub(Pair{Int,Int8}, (@UnionAll S Pair{Int,S})) @test !issub((@UnionAll T<:Real T), (@UnionAll T<:Integer T)) @test isequal_type((@UnionAll T Tuple{T,T}), (@UnionAll R Tuple{R,R})) @test !issub((@UnionAll T<:Integer @UnionAll S<:Number Tuple{T,S}), (@UnionAll T<:Integer @UnionAll S<:Number Tuple{S,T})) @test issub_strict((@UnionAll T Tuple{Array{T},Array{T}}), Tuple{Array, Array}) AUA = Vector{(@UnionAll T Vector{T})} UAA = (@UnionAll T Vector{Vector{T}}) @test !issub(AUA, UAA) @test !issub(UAA, AUA) @test !isequal_type(AUA, UAA) @test issub_strict((@UnionAll T Int), (@UnionAll T<:Integer Integer)) @test isequal_type((@UnionAll T @UnionAll S Tuple{T, Tuple{S}}), (@UnionAll T Tuple{T, @UnionAll S Tuple{S}})) @test !issub((@UnionAll T Pair{T,T}), Pair{Int,Int8}) @test !issub((@UnionAll T Pair{T,T}), Pair{Int,Int}) @test isequal_type((@UnionAll T Tuple{T}), Tuple{Any}) @test isequal_type((@UnionAll T<:Real Tuple{T}), Tuple{Real}) @test issub(Tuple{Vector{Integer}, Int}, @UnionAll T<:Integer @UnionAll S<:T Tuple{Vector{T},S}) @test !issub(Tuple{Vector{Integer}, Real}, @UnionAll T<:Integer Tuple{Vector{T},T}) @test !issub(Tuple{Int,String,Vector{Integer}}, @UnionAll T Tuple{T, T, Vector{T}}) @test !issub(Tuple{String,Int,Vector{Integer}}, @UnionAll T Tuple{T, T, Vector{T}}) @test !issub(Tuple{Int,String,Vector{Tuple{Integer}}}, @UnionAll T Tuple{T,T,Vector{Tuple{T}}}) @test issub(Tuple{Int,String,Vector{Any}}, @UnionAll T Tuple{T, T, Vector{T}}) @test isequal_type(Vector{Int}, Vector{(@UnionAll T<:Int T)}) @test isequal_type(Vector{Tuple{Any}}, Vector{(@UnionAll T Tuple{T})}) @test isequal_type(Vector{Tuple{Int,Int}}, Vector{(@UnionAll T<:Int Tuple{T,T})}) @test !issub(Vector{Tuple{Int,Integer}}, Vector{(@UnionAll T<:Integer Tuple{T,T})}) @test !issub(Pair{Int,Int8}, (@UnionAll T Pair{T,T})) @test !issub(Tuple{Vector{Int}, Integer}, @UnionAll T<:Integer Tuple{Vector{T},T}) @test !issub(Tuple{Integer, Vector{Int}}, @UnionAll T<:Integer Tuple{T, Vector{T}}) @test !issub(Pair{Vector{Int},Integer}, @UnionAll T Pair{Vector{T},T}) @test issub(Pair{Vector{Int},Int}, @UnionAll T Pair{Vector{T},T}) @test issub(Tuple{Integer,Int}, @UnionAll T<:Integer @UnionAll S<:T Tuple{T,S}) @test !issub(Tuple{Integer,Int}, @UnionAll T<:Int @UnionAll S<:T Tuple{T,S}) @test !issub(Tuple{Integer,Int}, @UnionAll T<:String @UnionAll S<:T Tuple{T,S}) @test issub(Tuple{Float32,Vector{Float32}}, @UnionAll T<:Real @UnionAll S<:AbstractVector{T} Tuple{T,S}) @test !issub(Tuple{Float32,Vector{Float64}}, @UnionAll T<:Real @UnionAll S<:AbstractVector{T} Tuple{T,S}) @test issub(Tuple{Float32,Vector{Real}}, @UnionAll T<:Real @UnionAll S<:AbstractVector{T} Tuple{T,S}) @test !issub(Tuple{Number,Vector{Real}}, @UnionAll T<:Real @UnionAll S<:AbstractVector{T} Tuple{T,S}) @test issub((@UnionAll Int<:T<:Integer T), @UnionAll T<:Real T) @test issub((@UnionAll Int<:T<:Integer Vector{T}), (@UnionAll T<:Real Vector{T})) @test issub((@UnionAll Int<:T<:Integer T), (@UnionAll Integer<:T<:Real T)) @test !issub((@UnionAll Int<:T<:Integer Vector{T}), (@UnionAll Integer<:T<:Real Vector{T})) X = (@UnionAll T<:Real @UnionAll S<:AbstractVector{T} Tuple{T,S}) Y = (@UnionAll A<:Real @UnionAll B<:AbstractVector{A} Tuple{A,B}) @test isequal_type(X,Y) Z = (@UnionAll A<:Real @UnionAll B<:AbstractVector{A} Tuple{Real,B}) @test issub_strict(X,Z) @test issub_strict((@UnionAll T @UnionAll S<:T Pair{T,S}), (@UnionAll T @UnionAll S Pair{T,S})) @test issub_strict((@UnionAll T @UnionAll S>:T Pair{T,S}), (@UnionAll T @UnionAll S Pair{T,S})) # these would be correct if the diagonal rule applied to type vars occurring # only once in covariant position. #@test issub_strict((@UnionAll T Tuple{Ref{T}, T}), # (@UnionAll T @UnionAll S<:T Tuple{Ref{T},S})) #@test issub_strict((@UnionAll T Tuple{Ref{T}, T}), # (@UnionAll T @UnionAll S<:T @UnionAll R<:S Tuple{Ref{T},R})) @test isequal_type((@UnionAll T Tuple{Ref{T}, T}), (@UnionAll T @UnionAll T<:S<:T Tuple{Ref{T},S})) @test issub_strict((@UnionAll T Tuple{Ref{T}, T}), (@UnionAll T @UnionAll S>:T Tuple{Ref{T}, S})) A = Tuple{T,Ptr{T}} where T B = Tuple{Ptr{T},T} where T C = Tuple{Ptr{T},Ptr{S}} where {T>:Ptr, S>:Ptr} D = Tuple{Ptr{T},Ptr{S}} where {T>:Ptr, S>:Ptr{T}} E = Tuple{Ptr{S},Ptr{T}} where {T>:Ptr, S>:Ptr{T}} @test !issub(A, B) @test !issub(B, A) @test issub_strict(C, A) @test issub_strict(C, B) @test issub_strict(C, D) @test issub_strict(Union{D,E}, A) @test issub_strict(Union{D,E}, B) @test issub_strict((@UnionAll T>:Ptr @UnionAll Ptr<:S<:Ptr Tuple{Ptr{T},Ptr{S}}), (@UnionAll T>:Ptr @UnionAll S>:Ptr{T} Tuple{Ptr{T},Ptr{S}})) @test !issub((@UnionAll T>:Ptr @UnionAll S>:Ptr Tuple{Ptr{T},Ptr{S}}), (@UnionAll T>:Ptr @UnionAll Ptr{T}<:S<:Ptr Tuple{Ptr{T},Ptr{S}})) @test !issub((@UnionAll T>:Integer @UnionAll S>:Ptr Tuple{Ptr{T},Ptr{S}}), B) @test issub((@UnionAll T>:Ptr @UnionAll S>:Integer Tuple{Ptr{T},Ptr{S}}), B) # issue #23327 @test !issub((Type{AbstractArray{Array{T}} where T}), Type{AbstractArray{S}} where S) @test !issub((Val{AbstractArray{Array{T}} where T}), Val{AbstractArray{T}} where T) @test !issub((Array{Array{Array{T}} where T}), Array{Array{T}} where T) @test !issub((Vector{Vector{T}} where T), AbstractArray{Vector}) @test !issub((Ref{Pair{Pair{T, R}, R} where R} where T), (Ref{Pair{A, B} where B} where A)) @test !issub((Ref{Pair{Pair{A, B}, B} where B} where A), (Ref{Pair{A, B2} where B2 <: B} where A where B)) @test !issub(Tuple{Type{Vector{T}} where T, Vector{Float64}}, Tuple{Type{T}, T} where T) @test !issub(Tuple{Vector{Float64}, Type{Vector{T}} where T}, Tuple{T, Type{T}} where T) @test !issub(Tuple{Type{Ref{T}} where T, Vector{Float64}}, Tuple{Ref{T}, T} where T) @test !issub(Tuple{Type{Ref{T}} where T, Ref{Float64}}, Tuple{Type{T},T} where T) end # level 4: Union function test_4() @test isequal_type(Union{Bottom,Bottom}, Bottom) @test issub_strict(Int, Union{Int,String}) @test issub_strict(Union{Int,Int8}, Integer) @test isequal_type(Union{Int,Int8}, Union{Int,Int8}) @test isequal_type(Union{Int,Integer}, Integer) @test isequal_type(Tuple{Union{Int,Int8},Int16}, Union{Tuple{Int,Int16},Tuple{Int8,Int16}}) @test issub_strict(Tuple{Int,Int8,Int}, Tuple{Vararg{Union{Int,Int8}}}) @test issub_strict(Tuple{Int,Int8,Int}, Tuple{Vararg{Union{Int,Int8,Int16}}}) # nested unions @test !issub(Union{Int,Ref{Union{Int,Int8}}}, Union{Int,Ref{Union{Int8,Int16}}}) A = Int64; B = Int8 C = Int16; D = Int32 @test issub(Union{Union{A,Union{A,Union{B,C}}}, Union{D,Bottom}}, Union{Union{A,B},Union{C,Union{B,D}}}) @test !issub(Union{Union{A,Union{A,Union{B,C}}}, Union{D,Bottom}}, Union{Union{A,B},Union{C,Union{B,A}}}) @test isequal_type(Union{Union{A,B,C}, Union{D}}, Union{A,B,C,D}) @test isequal_type(Union{Union{A,B,C}, Union{D}}, Union{A,Union{B,C},D}) @test isequal_type(Union{Union{Union{Union{A}},B,C}, Union{D}}, Union{A,Union{B,C},D}) @test issub_strict(Union{Union{A,C}, Union{D}}, Union{A,B,C,D}) @test !issub(Union{Union{A,B,C}, Union{D}}, Union{A,C,D}) # obviously these unions can be simplified, but when they aren't there's trouble X = Union{Union{A,B,C},Union{A,B,C},Union{A,B,C},Union{A,B,C}, Union{A,B,C},Union{A,B,C},Union{A,B,C},Union{A,B,C}} Y = Union{Union{D,B,C},Union{D,B,C},Union{D,B,C},Union{D,B,C}, Union{D,B,C},Union{D,B,C},Union{D,B,C},Union{A,B,C}} @test issub_strict(X,Y) end # level 5: union and UnionAll function test_5() u = Union{Int8,Int} @test issub(Tuple{String,Vector{Int}}, (@UnionAll T Union{Tuple{T,Vector{T}}, Tuple{T,Vector{Int}}})) @test issub(Tuple{Union{Vector{Int},Vector{Int8}}}, @UnionAll T Tuple{Vector{T}}) @test !issub(Tuple{Union{Vector{Int},Vector{Int8}},Vector{Int}}, @UnionAll T Tuple{Vector{T}, Vector{T}}) @test !issub(Tuple{Union{Vector{Int},Vector{Int8}},Vector{Int8}}, @UnionAll T Tuple{Vector{T}, Vector{T}}) @test !issub(Vector{Int}, @UnionAll T>:u Vector{T}) @test issub(Vector{Integer}, @UnionAll T>:u Vector{T}) @test issub(Vector{Union{Int,Int8}}, @UnionAll T>:u Vector{T}) @test issub((@UnionAll Int<:T<:u Vector{T}), (@UnionAll Int<:T<:u Vector{T})) # with varargs @test !issub(Array{Tuple{Array{Int},Array{Vector{Int16}},Array{Vector{Int}},Array{Int}}}, @UnionAll T<:(@UnionAll S Tuple{Vararg{Union{Array{S}, Array{Vector{S}}}}}) Array{T}) @test issub(Array{Tuple{Array{Int},Array{Vector{Int}},Array{Vector{Int}},Array{Int}}}, @UnionAll T<:(@UnionAll S Tuple{Vararg{Union{Array{S}, Array{Vector{S}}}}}) Array{T}) @test !issub(Tuple{Array{Int},Array{Vector{Int16}},Array{Vector{Int}},Array{Int}}, @UnionAll S Tuple{Vararg{Union{Array{S},Array{Vector{S}}}}}) @test issub(Tuple{Array{Int},Array{Vector{Int}},Array{Vector{Int}},Array{Int}}, @UnionAll S Tuple{Vararg{Union{Array{S},Array{Vector{S}}}}}) B = @UnionAll S<:u Tuple{S, Tuple{Any,Any,Any}, Ref{S}} # these tests require renaming in issub_unionall @test issub((@UnionAll T<:B Tuple{Int8, T, Ref{Int8}}), B) @test !issub((@UnionAll T<:B Tuple{Int8, T, Ref{T}}), B) # the `convert(Type{T},T)` pattern, where T is a Union # required changing priority of unions and vars @test issub(Tuple{Vector{u},Int}, @UnionAll T Tuple{Vector{T}, T}) @test issub(Tuple{Vector{u},Int}, @UnionAll T @UnionAll S<:T Tuple{Vector{T}, S}) @test !issub(Ref{Union{Ref{Int},Ref{Int8}}}, @UnionAll T Ref{Ref{T}}) @test issub(Tuple{Union{Ref{Int},Ref{Int8}}}, @UnionAll T Tuple{Ref{T}}) @test !issub(Ref{Union{Ref{Int},Ref{Int8}}}, Union{Ref{Ref{Int}}, Ref{Ref{Int8}}}) @test isequal_type(Ref{Tuple{Union{Int,Int8},Int16}}, Ref{Union{Tuple{Int,Int16},Tuple{Int8,Int16}}}) @test isequal_type(Ref{T} where T<:Tuple{Union{Int,Int8},Int16}, Ref{T} where T<:Union{Tuple{Int,Int16},Tuple{Int8,Int16}}) @test isequal_type(Ref{Tuple{Union{Int,Int8},Int16,T}} where T, Ref{Union{Tuple{Int,Int16,S},Tuple{Int8,Int16,S}}} where S) # issue #32726 @test Tuple{Type{Any}, Int, Float64, String} <: Tuple{Type{T}, Vararg{T}} where T end # tricky type variable lower bounds function test_6() @test issub((@UnionAll S<:Int (@UnionAll R<:String Tuple{S,R,Vector{Any}})), (@UnionAll T Tuple{T, T, Vector{T}})) @test !issub((@UnionAll S<:Int (@UnionAll R<:String Tuple{S,R,Vector{Integer}})), (@UnionAll T Tuple{T, T, Vector{T}})) t = @UnionAll T Tuple{T,T,Ref{T}} @test isequal_type(t, @UnionAll S Tuple{S,S,Ref{S}}) @test !issub((@UnionAll T Tuple{T,String,Ref{T}}), (@UnionAll T Tuple{T,T,Ref{T}})) @test !issub((@UnionAll T Tuple{T,Ref{T},String}), (@UnionAll T Tuple{T,Ref{T},T})) i = Int; ai = Integer @test isequal_type((@UnionAll i<:T<:i Ref{T}), Ref{i}) @test isequal_type((@UnionAll ai<:T<:ai Ref{T}), Ref{ai}) # Pair{T,S} <: Pair{T,T} can be true with certain bounds @test issub_strict((@UnionAll i<:T<:i @UnionAll i<:S<:i Pair{T,S}), @UnionAll T Pair{T,T}) @test issub_strict(Tuple{i, Ref{i}}, (@UnionAll T @UnionAll S<:T Tuple{S,Ref{T}})) @test !issub(Tuple{Real, Ref{i}}, (@UnionAll T @UnionAll S<:T Tuple{S,Ref{T}})) # S >: T @test issub_strict(Tuple{Real, Ref{i}}, (@UnionAll T @UnionAll S>:T Tuple{S,Ref{T}})) @test !issub(Tuple{Ref{i}, Ref{ai}}, (@UnionAll T @UnionAll S>:T Tuple{Ref{S},Ref{T}})) @test issub_strict(Tuple{Ref{Real}, Ref{ai}}, (@UnionAll T @UnionAll S>:T Tuple{Ref{S},Ref{T}})) @test issub_strict(Tuple{Real, Ref{Tuple{i}}}, (@UnionAll T @UnionAll S>:T Tuple{S,Ref{Tuple{T}}})) @test !issub(Tuple{Ref{Tuple{i}}, Ref{Tuple{ai}}}, (@UnionAll T @UnionAll S>:T Tuple{Ref{Tuple{S}},Ref{Tuple{T}}})) @test issub_strict(Tuple{Ref{Tuple{Real}}, Ref{Tuple{ai}}}, (@UnionAll T @UnionAll S>:T Tuple{Ref{Tuple{S}},Ref{Tuple{T}}})) # (@UnionAll x<:T<:x Q{T}) == Q{x} @test isequal_type(Ref{Ref{i}}, Ref{@UnionAll i<:T<:i Ref{T}}) @test isequal_type(Ref{Ref{i}}, @UnionAll i<:T<:i Ref{Ref{T}}) @test isequal_type((@UnionAll i<:T<:i Ref{Ref{T}}), Ref{@UnionAll i<:T<:i Ref{T}}) @test !issub((@UnionAll i<:T<:i Ref{Ref{T}}), Ref{@UnionAll T<:i Ref{T}}) u = Union{Int8,Int64} A = Ref{Bottom} B = @UnionAll S<:u Ref{S} @test issub(Ref{B}, @UnionAll A<:T<:B Ref{T}) C = @UnionAll S<:u S @test issub(Ref{C}, @UnionAll u<:T<:u Ref{T}) BB = @UnionAll S<:Bottom S @test issub(Ref{B}, @UnionAll BB<:U<:B Ref{U}) end # uncategorized function test_7() @test isequal_type(Ref{Union{Int16, T}} where T, Ref{Union{Int16, S}} where S) @test isequal_type(Pair{Union{Int16, T}, T} where T, Pair{Union{Int16, S}, S} where S) end function test_Type() @test issub_strict(DataType, Type) @test issub_strict(Union, Type) @test issub_strict(UnionAll, Type) @test issub_strict(typeof(Bottom), Type) @test !issub(TypeVar, Type) @test !issub(Type, TypeVar) @test !issub(DataType, @UnionAll T<:Number Type{T}) # `Type{Int}`'s members include `UnionAll` spellings of `Int`'s `==`-class, # so it is not a subtype of any single kind (#33136) @test !issub(Type{Int}, DataType) @test issub_strict(Type{Int}, Union{DataType,UnionAll}) @test !issub((@UnionAll T<:Integer Type{T}), DataType) @test isequal_type(Type{AbstractArray}, Type{AbstractArray}) @test !issub(Type{Int}, Type{Integer}) @test issub((@UnionAll T<:Integer Type{T}), (@UnionAll T<:Number Type{T})) @test isa(Int, @UnionAll T<:Number Type{T}) @test !isa(DataType, @UnionAll T<:Number Type{T}) @test !(DataType <: (@UnionAll T<:Type Type{T})) @test isa(DataType, (@UnionAll T<:Type Type{T})) @test isa(Tuple{},Type{Tuple{}}) @test !(Tuple{Int,} <: (@UnionAll T<:Tuple Type{T})) @test isa(Tuple{Int}, (@UnionAll T<:Tuple Type{T})) @test !isa(Int, Type{>:String}) @test isa(Union{Int,String}, Type{>:String}) @test isa(Any, Type{>:String}) # `Type{Int}` also has `UnionAll`-tagged members under `==`-class semantics # (#33136), so no concrete `T` covers both slots (the dispatch key # `Tuple{TypeEgal{Int},TypeEgal{Int8}}` still matches with `T == DataType`) @test !issub(Tuple{Type{Int},Type{Int8}}, Tuple{T,T} where T) @test issub(Tuple{Core.TypeEgal{Int},Core.TypeEgal{Int8}}, Tuple{T,T} where T) @test !issub(Tuple{Type{Int},Type{Union{}}}, Tuple{T,T} where T) # issue #20476 @test issub(Tuple{Type{Union{Type{UInt32}, Type{UInt64}}}, Type{UInt32}}, Tuple{Type{T},T} where T) @test isequal_type(Core.TypeofBottom, Type{Union{}}) @test issub(Core.TypeofBottom, Type{T} where T<:Real) for b in (Type{T} where T, Type{Union{T,S}} where {T,S}) for a in (Type{Union{}}, Core.TypeofBottom) @test issub(a, b) end @test isa(Union{}, b) end end # old subtyping tests from test/core.jl function test_old() @test Int8 <: Integer @test Int32 <: Integer @test Tuple{Int8,Int8} <: Tuple{Integer,Integer} @test !(AbstractMatrix{Float64} <: AbstractMatrix{Number}) @test !(AbstractVector{Float64} <: AbstractMatrix{Float64}) @test Tuple{Integer,Vararg{Integer}} <: Tuple{Integer,Vararg{Real}} @test Tuple{Integer,Float64,Vararg{Integer}} <: Tuple{Integer,Vararg{Number}} @test Tuple{Integer,Float64} <: Tuple{Integer,Vararg{Number}} @test Tuple{Int32,} <: Tuple{Vararg{Number}} @test Tuple{} <: Tuple{Vararg{Number}} @test !(Tuple{Vararg{Int32}} <: Tuple{Int32,}) @test !(Tuple{Vararg{Int32}} <: Tuple{Number,Integer}) @test !(Tuple{Vararg{Integer}} <: Tuple{Integer,Integer,Vararg{Integer}}) @test !(Vector{Int8} <: Vector{Any}) @test !(Vector{Any} <: Vector{Int8}) @test Vector{Int8} <: Vector{Int8} @test !(Type{Bottom} <: Type{Int32}) @test !(Vector{Float64} <: Vector{Union{Float64,Float32}}) @test !isa(Array,Type{Any}) @test Type{Complex} <: UnionAll @test isa(Complex,Type{Complex}) # `Type` (i.e. `Type{T} where T`) and `AnyType` denote the same set of all # types, so they are equal; the type cache canonicalizes them as parameters. @test Type <: Core.AnyType @test Core.AnyType <: Type @test Type == Core.AnyType @test Vector{Type} === Vector{Core.AnyType} # bounded `Type{}`s are strict subtypes of `AnyType`, not equal to it @test (Type{T} where T<:Real) != Core.AnyType @test (Type{T} where T<:Real) <: Core.AnyType @test !(Core.AnyType <: (Type{T} where T<:Real)) # `Type{Type{T}} where T` (unbounded `T`) contains every `Type{X}` value, # so the bare `TypeEq` kind is a subtype of it; the containment is strict, # since it also contains `UnionAll` spellings like `Type{S} where Int<:S<:Int` @test Core.TypeEq <: (Type{Type{T}} where T) @test Core.TypeEq != (Type{Type{T}} where T) @test !((Type{Type{T}} where T) <: Core.TypeEq) @test !(DataType <: (Type{Type{T}} where T)) # a `Type{X}` never lies in a single kind, even when instantiated: its # members include `UnionAll` spellings such as `Ref{S} where Int<:S<:Int` @test !((Type{Ref{T}} where T<:Real) <: DataType) @test (Type{Ref{T}} where T<:Real) <: Union{DataType,UnionAll} @test !((Type{Union{Int,T}} where T<:Real) <: Union) @test !(Type{Ptr{Bottom}} <: Type{Ptr}) @test !(Type{Rational{Int}} <: Type{Rational}) @test Tuple{} <: Tuple{Vararg} @test Tuple{Int,Int} <: Tuple{Vararg} @test Tuple{} <: @UnionAll N NTuple{N} @test !(Type{Tuple{}} <: Type{Tuple{Vararg}}) @test Type{Tuple{}} <: (@UnionAll N Type{NTuple{N}}) @test !(Type{Array{Integer}} <: Type{AbstractArray{Integer}}) @test !(Type{Array{Integer}} <: Type{@UnionAll T<:Integer Array{T}}) # issue #6561 # TODO: note that NTuple now means "tuples of all the same type" #@test (Array{Tuple} <: Array{NTuple}) @test issub_strict(NTuple, Tuple) @test issub_strict(NTuple, Tuple{Vararg}) @test isequal_type(Tuple, Tuple{Vararg}) #@test (Array{Tuple{Vararg{Any}}} <: Array{NTuple}) #@test (Array{Tuple{Vararg}} <: Array{NTuple}) @test !(Type{Tuple{Nothing}} <: Tuple{Type{Nothing}}) end const easy_menagerie = Any[Any, Int, Int8, Integer, Real, Vector{Int}, AbstractVector{Int}, Tuple{Int,Vararg{Integer}}, Tuple{Integer,Vararg{Int}}, Tuple{}, Union{Int,Int8}, (@UnionAll T Vector{T}), (@UnionAll T Pair{T,T}), (@UnionAll T @UnionAll S Pair{T,S}), Pair{Int,Int8}, (@UnionAll S Pair{Int,S}), (@UnionAll T Tuple{T,T}), (@UnionAll T<:Integer Tuple{T,T}), (@UnionAll T @UnionAll S Tuple{T,S}), (@UnionAll T<:Integer @UnionAll S<:Number Tuple{T,S}), (@UnionAll T<:Integer @UnionAll S<:Number Tuple{S,T}), Vector{(@UnionAll T Vector{T})}, (@UnionAll T Vector{Vector{T}}), Vector{(@UnionAll T<:Int T)}, (@UnionAll T<:Real @UnionAll S<:AbstractVector{T} Tuple{T,S}), Union{Int,Ref{Union{Int,Int8}}}, ] const hard_menagerie = Any[(@UnionAll T Union{Tuple{T,Vector{T}}, Tuple{T,Vector{Int}}})] function add_variants!(types) new = Any[] for T in types push!(new, Ref{T}) push!(new, Tuple{T}) push!(new, Tuple{T,T}) push!(new, Tuple{Vararg{T}}) push!(new, @UnionAll S<:T S) push!(new, @UnionAll S<:T Ref{S}) end append!(types, new) end add_variants!(easy_menagerie) add_variants!(hard_menagerie) push!(easy_menagerie, Bottom) push!(easy_menagerie, Ref{Bottom}) push!(easy_menagerie, @UnionAll N NTuple{N,Bottom}) push!(easy_menagerie, @UnionAll S<:Bottom Ref{S}) const menagerie = [easy_menagerie; hard_menagerie] function test_properties() x→y = !x || y ¬T = @UnionAll X>:T Ref{X} for T in menagerie # top and bottom identities @test issub(Bottom, T) @test issub(T, Any) @test issub(T, Bottom) → isequal_type(T, Bottom) @test issub(Any, T) → isequal_type(T, Any) # unionall identity @test isequal_type(T, @UnionAll S<:T S) @test isequal_type(Ref{T}, @UnionAll T<:U<:T Ref{U}) # equality under renaming if isa(T, UnionAll) lb, ub = T.var.lb, T.var.ub @test isequal_type(T, (@UnionAll lb<:Y<:ub T{Y})) end # inequality under wrapping @test !isequal_type(T, Ref{T}) for S in menagerie issubTS = issub(T, S) # transitivity if issubTS for R in menagerie if issub(S, R) @test issub(T, R) # issub(T,S) ∧ issub(S,R) → issub(T,R) @test issub(Ref{S}, @UnionAll T<:U<:R Ref{U}) end end end # union subsumption @test isequal_type(T, Union{T,S}) → issub(S, T) # invariance @test isequal_type(T, S) == isequal_type(Ref{T}, Ref{S}) # covariance if T !== Bottom && S !== Bottom @test issubTS == issub(Tuple{T}, Tuple{S}) @test issubTS == issub(Tuple{Vararg{T}}, Tuple{Vararg{S}}) @test issubTS == issub(Tuple{T}, Tuple{Vararg{S}}) end # pseudo-contravariance @test issubTS == issub(¬S, ¬T) end end end macro testintersect(a, b, result) if isa(result, Expr) && result.head === :call && length(result.args) == 2 && result.args[1] === :! result = result.args[2] cmp = :(!=) else cmp = :(==) end a = esc(a) b = esc(b) result = esc(result) # use a manual macrocall expression since Test will examine this __source__ value return quote # test real intersect $(Expr(:macrocall, :var"@test", __source__, :($cmp(_type_intersect($a, $b), $result)))) $(Expr(:macrocall, :var"@test", __source__, :($cmp(_type_intersect($b, $a), $result)))) # test simplified intersect if !($result === Union{}) $(Expr(:macrocall, :var"@test", __source__, :(typeintersect($a, $b) != Union{}))) $(Expr(:macrocall, :var"@test", __source__, :(typeintersect($b, $a) != Union{}))) end end end abstract type IT4805_2{N, T} end abstract type AbstractThing{T,N} end mutable struct ConcreteThing{T<:AbstractFloat,N} <: AbstractThing{T,N} end mutable struct A11136 end mutable struct B11136 end abstract type Foo11367 end abstract type AbstractTriangular{T,S<:AbstractMatrix} <: AbstractMatrix{T} end struct UpperTriangular{T,S<:AbstractMatrix} <: AbstractTriangular{T,S} end struct UnitUpperTriangular{T,S<:AbstractMatrix} <: AbstractTriangular{T,S} end struct SIQ20671{T<:Number,m,kg,s,A,K,mol,cd,rad,sr} <: Number val::T end function test_intersection() @testintersect(Vector{Float64}, Vector{Union{Float64,Float32}}, Bottom) @testintersect(Array{Bottom}, (@UnionAll T AbstractArray{T}), !Bottom) @testintersect(Tuple{Type{Ptr{UInt8}}, Ptr{Bottom}}, (@UnionAll T Tuple{Type{Ptr{T}},Ptr{T}}), Bottom) @testintersect(Tuple{AbstractRange{Int},Tuple{Int,Int}}, (@UnionAll T Tuple{AbstractArray{T},Dims}), Tuple{AbstractRange{Int},Tuple{Int,Int}}) @testintersect((@UnionAll Integer<:T<:Number Array{T}), (@UnionAll T<:Number Array{T}), (@UnionAll Integer<:T<:Number Array{T})) @testintersect((@UnionAll Integer<:T<:Number Array{T}), (@UnionAll T<:Real Array{T}), (@UnionAll Integer<:T<:Real Array{T})) @testintersect((@UnionAll Integer<:T<:Number Array{T}), (@UnionAll T<:String Array{T}), Bottom) @testintersect((@UnionAll Integer<:T<:Number Array{T}), (@UnionAll String<:T<:AbstractString Array{T}), Bottom) @testintersect((@UnionAll T<:Number Array{T}), (@UnionAll T<:String Array{T}), Array{Bottom}) @testintersect((@UnionAll T Tuple{T, AbstractArray{T}}), Tuple{Number, Vector{Int}}, Tuple{Int, Vector{Int}}) @testintersect((@UnionAll T Tuple{T, AbstractArray{T}}), Tuple{Int, Vector{Number}}, Tuple{Int, Vector{Number}}) # TODO: improve this result #@testintersect((@UnionAll S Tuple{S,Vector{S}}), (@UnionAll T<:Real Tuple{T,AbstractVector{T}}), # (@UnionAll S<:Real Tuple{S,Vector{S}})) @testintersect((@UnionAll S Tuple{S,Vector{S}}), (@UnionAll T<:Real Tuple{T,AbstractVector{T}}), (@UnionAll S<:Real Tuple{Real,Vector{S}})) # typevar corresponding to a type it will end up being neither greater than nor # less than @testintersect((@UnionAll T Tuple{T, Ref{T}}), Tuple{Array{Int}, Ref{AbstractVector}}, Tuple{Vector{Int}, Ref{AbstractVector}}) @testintersect((@UnionAll T Tuple{T, AbstractArray{T}}), Tuple{Any, Vector{Number}}, Tuple{Number, Vector{Number}}) @testintersect((@UnionAll T Tuple{Array{T}, Array{T}}), Tuple{Array, Array{Any}}, !Bottom) @testintersect((@UnionAll T Tuple{T,T}), Tuple{Real, Real}, (@UnionAll T<:Real Tuple{T,T})) @testintersect((@UnionAll T Tuple{T}), Tuple{Real}, Tuple{Real}) @testintersect((@UnionAll T Tuple{T,T}), Tuple{Union{Float64,Int64},Int64}, Tuple{Int64,Int64}) @testintersect((@UnionAll T Tuple{T,T}), Tuple{Int64,Union{Float64,Int64}}, Tuple{Int64,Int64}) @testintersect((@UnionAll Z Tuple{Z,Z}), (@UnionAll T<:Integer @UnionAll S<:Number Tuple{T,S}), @UnionAll Z<:Integer Tuple{Z,Z}) @testintersect((@UnionAll Z Pair{Z,Z}), (@UnionAll T<:Integer @UnionAll S<:Number Pair{T,S}), @UnionAll Z<:Integer Pair{Z,Z}) @testintersect((@UnionAll T<:Vector Type{T}), (@UnionAll N Type{@UnionAll S<:Number Array{S,N}}), Type{@UnionAll S<:Number Vector{S}}) @testintersect((@UnionAll T Tuple{Type{Vector{T}},Vector{T}}), Tuple{Type{AbstractVector},Vector{Int}}, Bottom) @testintersect(Tuple{Type{Vector{ComplexF64}}, AbstractVector}, (@UnionAll T @UnionAll S @UnionAll N Tuple{Type{Array{T,N}}, Array{S,N}}), Tuple{Type{Vector{ComplexF64}},Vector}) @testintersect(Tuple{Type{Vector{ComplexF64}}, AbstractArray}, (@UnionAll T @UnionAll S @UnionAll N Tuple{Type{Array{T,N}}, Array{S,N}}), Tuple{Type{Vector{ComplexF64}},Vector}) @testintersect(Type{Array}, Type{AbstractArray}, Bottom) @testintersect(Type{Tuple{Bool,Vararg{Int}}}, Type{@UnionAll T Tuple{Vararg{T}}}, Bottom) @testintersect(Type{Tuple{Bool,Vararg{Int}}}, Type{@UnionAll T Tuple{T,Vararg{T}}}, Bottom) @testintersect((@UnionAll T Tuple{Vararg{T}}), Tuple{Float64,Int}, Bottom) @testintersect((@UnionAll T Tuple{Rational{T},T}), Tuple{Rational{Integer},Int}, Tuple{Rational{Integer},Int}) @testintersect((@UnionAll T Pair{T,Ptr{T}}), (@UnionAll S Pair{Ptr{S},S}), Bottom) let A = Tuple{T,Ptr{T}} where T, B = Tuple{Ptr{S},S} where S, # The precise A∩B is `Tuple{Ptr{S},Ptr{T}} where S>:Ptr{T} where T>:Ptr{S}`, but the # mutually-forward-referencing bounds make it inexpressible as a Julia type. ILB is a # representable strict subset of A∩B; W is a witness inhabitant of A∩B not in ILB. ILB = Union{Tuple{Ptr{T},Ptr{S}} where S>:Ptr{T} where T>:Ptr, Tuple{Ptr{S},Ptr{T}} where S>:Ptr{T} where T>:Ptr}, Bptr = Ptr{<:Ptr}, W = Tuple{Ptr{Bptr}, Ptr{Bptr}} let IActual1 = typeintersect(B, A), IActual2 = typeintersect(A, B) @test W <: A && W <: B @test !(W <: ILB) @test IActual1 == IActual2 @test IActual2 >: ILB @test IActual2 >: W end let A1 = (Tuple{Ptr{Z}, Ptr{Y}} where Y>:Ptr{Z}) where Z, A2 = (Tuple{Ptr{Z}, Ptr{Y}} where Z>:Ptr{Y}) where Y, I = typeintersect(A1, A2), X = Tuple{Ptr{Bptr}, Ptr{Ptr{Bptr}}} @test X <: A1 && X <: A2 @test_broken X <: I end end @testintersect((@UnionAll N Tuple{NTuple{N,Integer},NTuple{N,Integer}}), Tuple{Tuple{Integer,Integer}, Tuple{Vararg{Integer}}}, Tuple{Tuple{Integer,Integer}, Tuple{Integer,Integer}}) @testintersect((@UnionAll N Tuple{NTuple{N,Integer},NTuple{N,Integer}}), Tuple{Tuple{Vararg{Integer}}, Tuple{Integer,Integer}}, Tuple{Tuple{Integer,Integer}, Tuple{Integer,Integer}}) @test isequal_type(typeintersect((@UnionAll N Tuple{NTuple{N,Any},Array{Int,N}}), Tuple{Tuple{Int,Vararg{Int}},Array}), @UnionAll N Tuple{Tuple{Int,Vararg{Int}},Array{Int,N}}) @testintersect((@UnionAll N Tuple{NTuple{N,Any},Array{Int,N}}), Tuple{Tuple{Int,Vararg{Int}},Matrix{Int}}, Tuple{Tuple{Int,Int}, Matrix{Int}}) @testintersect(Type{Any},Type{Complex}, Bottom) @testintersect(Type{Any},(@UnionAll T<:Real Type{T}), Bottom) @testintersect(Type{Function},Union,Bottom) @testintersect(Type{Int32}, DataType, Type{Int32}) @testintersect(DataType, Type, !Bottom) @testintersect(Union, Type, !Bottom) @testintersect(DataType, Type{Int}, !Bottom) @testintersect(DataType, (@UnionAll T<:Int Type{T}), !Bottom) @testintersect(DataType, (@UnionAll T<:Integer Type{T}), !Bottom) @testintersect(Tuple{Vararg{Int}}, Tuple{Vararg{Bool}}, Tuple{}) @testintersect(Type{Tuple{Vararg{Int}}}, Type{Tuple{Vararg{Bool}}}, Bottom) @testintersect(Tuple{Bool,Vararg{Int}}, Tuple{Vararg{Bool}}, Tuple{Bool}) let M = @UnionAll T<:Union{Float32,Float64} Matrix{T} @testintersect(AbstractArray, M, M) end @testintersect((@UnionAll N Tuple{Array{Int,N},Vararg{Int,N}}), Tuple{Vector{Int},Real,Real,Real}, Bottom) @testintersect((@UnionAll N Tuple{Array{Int,N},Vararg{Int,N}}), Tuple{Array{Int,0}}, Tuple{Array{Int,0}}) @testintersect((@UnionAll N Tuple{Array{Int,N},Vararg{Int,N}}), Tuple{Matrix{Int}}, Bottom) @testintersect(Tuple{Int,Vararg{Int}}, Tuple{Int,Int,Int,Vararg{Float64}}, Tuple{Int,Int,Int}) @testintersect(Tuple{Int,Vararg{Int}}, Tuple{Int,Vararg{Float64}}, Tuple{Int}) @testintersect((@UnionAll N Tuple{Array{Int,N},Vararg{Int,N}}), Tuple{Matrix{Int},Int,Int,Vararg{Float64}}, Tuple{Matrix{Int},Int,Int}) @testintersect((@UnionAll N Tuple{Array{Int,N},Vararg{Int,N}}), Tuple{Matrix{Int},Int,Vararg{Float64}}, Bottom) @testintersect(Tuple{Vector{Any}, Tuple{Int64, Int64, Vararg{Int64}}}, Tuple{Array{T,N}, Tuple{Vararg{Int64,N}}} where N where T, Bottom) @testintersect((@UnionAll T<:Union{Float64,Vector{Float64}} T), Real, Float64) # issue #4805 @testintersect((@UnionAll T<:Int Type{IT4805_2{1,T}}), (@UnionAll S<:(@UnionAll N IT4805_2{N,Int}) Type{S}), !Bottom) # issue #8851 @testintersect((@UnionAll T AbstractThing{T,2}), ConcreteThing, (@UnionAll T<:AbstractFloat ConcreteThing{T,2})) # issue #11136 and #11367 @testintersect((@UnionAll T Tuple{T, T}), (@UnionAll TB<:B11136 Tuple{A11136, TB}), Bottom) @testintersect((@UnionAll T Tuple{T, T}), (@UnionAll T2<:Foo11367 Tuple{Type{BigInt}, T2}), Bottom) # PR #12058 @testintersect((@UnionAll N NTuple{N,Int}), (@UnionAll N NTuple{N,Float64}), Tuple{}) @testintersect((@UnionAll T Tuple{Type{T},T}), Tuple{Type{Type{Float64}},Type{Int}}, Bottom) @testintersect((@UnionAll T T), Type{Int8}, Type{Int8}) # issue #14482 @testintersect((@UnionAll T Tuple{T}), Tuple{Type{Int8}}, Tuple{Type{Int8}}) @testintersect((@UnionAll T Tuple{Union{Int,T}, Union{Vector{T},Vector{String}}}), Tuple{Integer, Vector{Int8}}, Tuple{Union{Int,Int8}, Vector{Int8}}) @testintersect((@UnionAll T Tuple{Union{Int,T}, Union{Vector{T},Vector{String}}}), Tuple{Int8, Vector{String}}, Tuple{Int8, Vector{String}}) @testintersect((@UnionAll T Tuple{Union{Int,T}, Union{Vector{T},Vector{String}}}), Tuple{Int, Vector{Int8}}, Tuple{Int, Vector{Int8}}) @testintersect(( Tuple{Union{Int,String}, Union{Ref{Int}, Ref{String}}}), (@UnionAll T Tuple{T, Union{Ref{T}, Ref{String}}}), Union{Tuple{Int, Union{Ref{Int},Ref{String}}}, Tuple{String, Ref{String}}}) @testintersect((@UnionAll Z<:(@UnionAll T @UnionAll S Tuple{T,S}) Ref{Z}), (@UnionAll X<:(@UnionAll T Tuple{T,T}) Ref{X}), (@UnionAll X<:(@UnionAll T Tuple{T,T}) Ref{X})) @testintersect(Ref{@UnionAll T @UnionAll S Tuple{T,S}}, Ref{@UnionAll T Tuple{T,T}}, Bottom) # both of these answers seem acceptable #@testintersect(Tuple{T,T} where T<:Union{UpperTriangular, UnitUpperTriangular}, # Tuple{AbstractArray{T,N}, AbstractArray{T,N}} where N where T, # Union{Tuple{T,T} where T<:UpperTriangular{T1}, # Tuple{T,T} where T<:UnitUpperTriangular{T1}} where T) @testintersect(Tuple{T,T} where T<:Union{UpperTriangular, UnitUpperTriangular}, Tuple{AbstractArray{T,N}, AbstractArray{T,N}} where N where T, Tuple{T,T} where {T1, T<:Union{UpperTriangular{T1}, UnitUpperTriangular{T1}}}) @testintersect(DataType, Type, DataType) @testintersect(DataType, Type{T} where T<:Integer, Type{T} where T<:Integer) @testintersect(Union{DataType,Int}, Type, DataType) @testintersect(Union{DataType,Int}, Type{T} where T, DataType) # test typeintersect wrapper as well as _type_intersect @test typeintersect(Union{DataType,Int}, Type) === DataType @test typeintersect(Union{DataType,Int}, Type{T} where T) === DataType # since TypeofBottom is a singleton we can deduce its intersection with Type{...} @testintersect(Core.TypeofBottom, (Type{T} where T<:Tuple), Type{Union{}}) # since this T is inside the invariant ctor Type{}, we allow T == Any here @testintersect((Type{Tuple{Vararg{T}}} where T), Type{Tuple}, Type{Tuple}) # TODO: improve this @testintersect(Tuple{Type{S}, Tuple{Any, Vararg{Any}}} where S<:Tuple{Any, Vararg{Any}}, Tuple{Type{T}, T} where T, Tuple{Type{S}, Tuple{Any, Vararg{Any}}} where S<:Tuple{Any, Vararg{Any}}) # part of issue #20450 @testintersect(Tuple{Vector{Ref{T}}, Vector{Pair{M, V}}} where V where T where M, Tuple{Vector{Ref{T}}, Vector{Pair{M, T}}, SS} where T where M where SS, Union{}) @testintersect(Tuple{Vector{Ref{T}}, Vector{Pair{M, V}}, Int} where V where T where M, Tuple{Vector{Ref{T}}, Vector{Pair{M, T}}, Any} where T where M, Tuple{Vector{Ref{T}}, Vector{Pair{M, T}}, Int} where T where M) @testintersect(Tuple{Int, Ref{Pair{K,V}}} where V where K, Tuple{Any, Ref{Pair{T,T}} where T }, Tuple{Int, Ref{Pair{T,T}} where T }) @test_broken isequal_type(_type_intersect(Tuple{T,T} where T, Union{Tuple{S,Vector{Int64}},Tuple{S,Vector{S}}} where S), Union{Tuple{Vector{Int64},Vector{Int64}}, Tuple{Vector{T},Vector{T}} where T>:Vector}) # part of issue #20344 @testintersect(Tuple{Type{Tuple{Vararg{T}}}, Tuple} where T, Tuple{Type{Tuple{Vararg{T, N}}} where N where T, Any}, Bottom) @testintersect(Type{NTuple{N,UnitRange}} where N, Type{Tuple{Vararg{UnitRange}}}, Bottom) @testintersect(Type{NTuple{Z,UnitRange}} where Z, Type{NTuple{Z,String}} where Z, Type{Tuple{}}) # first union component sets N==0, but for the second N is unknown _, E = intersection_env(Tuple{Tuple{Vararg{Int}}, Any}, Tuple{Union{Base.DimsInteger{N},Base.Indices{N}}, Int} where N) @test length(E)==1 && isa(E[1], Core.SimpleVector) && E[1][1] isa TypeVar @testintersect(Tuple{Dict{Int,Int}, Ref{Pair{K,V}}} where V where K, Tuple{AbstractDict{Int,Int}, Ref{Pair{T,T}} where T}, Tuple{Dict{Int,Int}, Ref{Pair{K,K}}} where K) # issue #20643 @testintersect(Tuple{Ref{Pair{p2,T2}}, Pair{p1,Pair}} where T2 where p2 where p1, Tuple{Ref{Pair{p3,T3}}, Pair{p3}} where T3 where p3, Tuple{Ref{Pair{p1,T2}}, Pair{p1,Pair}} where T2 where p1) # issue #20998 _, E = intersection_env(Tuple{Int,Any,Any}, Tuple{T,T,S} where {T,S}) @test length(E) == 2 && E[1] == Int && isa(E[2], Core.SimpleVector) && E[2][1] isa TypeVar _, E = intersection_env(Tuple{Dict{Int,Type}, Type, Any}, Tuple{Dict{K,V}, Any, Int} where {K,V}) @test E[2] == Type # issue #20611 I, E = intersection_env(Tuple{Ref{Integer},Int,Any}, Tuple{Ref{Z},Z,Z} where Z) @test isequal_type(I, Tuple{Ref{Integer},Int,Integer}) @test E[1] == Integer # issue #21118 A = Tuple{Ref, Vararg{Any}} B = Tuple{Vararg{Union{Z,Ref,Nothing}}} where Z<:Union{Ref,Nothing} @test B <: _type_intersect(A, B) # TODO: this would be a better version of that test: #let T = _type_intersect(A, B) # @test T <: A # @test T <: B # @test Tuple{Ref, Vararg{Union{Ref,Nothing}}} <: T #end @testintersect(Tuple{Int,Any,Vararg{A}} where A>:Integer, Tuple{Any,Int,Vararg{A}} where A>:Integer, Tuple{Int,Int,Vararg{A}} where A>:Integer) # issue #21132 @testintersect(Pair{L,Tuple{L,Pair{L,HL}}} where {L,HL}, Pair{R,Tuple{Pair{R,HR},R}} where {R,HR}, Bottom) # X == Pair{X,...} is not satisfiable # issue #20671 --- this just took too long @testintersect(Tuple{Type{SIQ20671{T, mT, kgT, sT, AT, KT, molT, cdT, radT, srT}}, SIQ20671{S, mS, kgS, sS, AS, KS, molS, cdS, radS, srS}} where {T, mT, kgT, sT, AT, KT, molT, cdT, radT, srT, S, mS, kgS, sS, AS, KS, molS, cdS, radS, srS}, Tuple{Type{T}, T} where T, Tuple{Type{SIQ20671{T,mS,kgS,sS,AS,KS,molS,cdS,radS,srS}}, SIQ20671{T,mS,kgS,sS,AS,KS,molS,cdS,radS,srS}} where {T,mS,kgS,sS,AS,KS,molS,cdS,radS,srS}) # issue #21243 @testintersect(Tuple{Ref{Ref{T}} where T, Ref}, Tuple{Ref{T}, Ref{T}} where T, Tuple{Ref{Ref{T}}, Ref{Ref{T}}} where T) # issue #29208 @testintersect(Tuple{Ref{Ref{T}} where T, Ref{Ref{Int}}}, Tuple{Ref{T}, Ref{T}} where T, Tuple{Ref{Ref{Int}}, Ref{Ref{Int}}}) @testintersect(Tuple{Vector{Pair{K,V}}, Vector{Pair{K,V}}} where K where V, Tuple{(Vector{Pair{Ref{_2},_1}} where _2 where _1), Vector{Pair{Ref{Int64},Rational{Int64}}}}, Tuple{Vector{Pair{Ref{Int64},Rational{Int64}}}, Vector{Pair{Ref{Int64},Rational{Int64}}}}) @testintersect(Vector{>:Missing}, Vector{Int}, Union{}) # issue #23685 @testintersect(Pair{Type{Z},Z} where Z, Pair{Type{Ref{T}} where T, Ref{Float64}}, Bottom) @testintersect(Tuple{Type{Z},Z} where Z, Tuple{Type{Ref{T}} where T, Ref{Float64}}, !Bottom) @test_broken typeintersect(Tuple{Type{Z},Z} where Z, Tuple{Type{Ref{T}} where T, Ref{Float64}}) == Tuple{Type{Ref{Float64}},Ref{Float64}} # issue #32607 @testintersect(Type{<:Tuple{Integer,Integer}}, Type{Tuple{Int,T}} where T, Type{Tuple{Int,T}} where T<:Integer) @testintersect(Type{<:Tuple{Any,Vararg{Any}}}, Type{Tuple{Vararg{Int,N}}} where N, Type{Tuple{Int,Vararg{Int,N}}} where N) @testintersect(Type{<:Array}, Type{AbstractArray{T}} where T, Bottom) @testintersect(Tuple{Type{Tuple{Vararg{Integer}}}, Tuple}, Tuple{Type{Tuple{Vararg{V}}}, Tuple{Vararg{V}}} where {V}, Tuple{Type{Tuple{Vararg{Integer}}},Tuple{Vararg{Integer}}}) @testintersect(Tuple{Type{Tuple{Vararg{Union{Int,Symbol}}}}, Tuple}, Tuple{Type{Tuple{Vararg{V}}}, Tuple{Vararg{V}}} where {V}, Tuple{Type{Tuple{Vararg{Union{Int,Symbol}}}},Tuple{Vararg{Union{Int,Symbol}}}}) # non types @testintersect(Tuple{1}, Tuple{Any}, Tuple{1}) # tests for robustness after incorrect datatype allocation normalization @test typeintersect(Vector{Tuple{T, T} where Number<:T<:Number}, Vector{Tuple{Number, Number}}) === Vector{Tuple{T, T} where Number<:T<:Number} @test typeintersect(Vector{Tuple{Number, Number}}, Vector{Tuple{T, T} where Number<:T<:Number}) === Vector{Tuple{Number, Number}} end function test_intersection_properties() for i in eachindex(menagerie) T = menagerie[i] for j in eachindex(menagerie) S = menagerie[j] I = _type_intersect(T,S) I2 = _type_intersect(S,T) @test isequal_type(I, I2) if i > length(easy_menagerie) || j > length(easy_menagerie) # @test issub(I, T) || issub(I, S) else @test issub(I, T) && issub(I, S) end if issub(T, S) @test isequal_type(I, T) end end end end test_1() test_2() test_diagonal() test_3() test_4() test_5() test_6() test_7() test_Type() test_old() test_intersection() test_properties() test_intersection_properties() @testset "bound-expanded non-diagonal form is not equal to diagonal tuple form" begin A = Tuple{S,T} where {T, S<:Tuple{T}} B = Tuple{Tuple{T},T} where T @test Tuple{Tuple{Int}, Real} <: A @test !(Tuple{Tuple{Int}, Real} <: B) @test B <: A @test !(A <: B) @test A != B A′ = Tuple{T,S} where {T, S<:Tuple{T}} B′ = Tuple{T,Tuple{T}} where T @test Tuple{Real, Tuple{Int}} <: A′ @test !(Tuple{Real, Tuple{Int}} <: B′) @test B′ <: A′ @test !(A′ <: B′) @test A′ != B′ end @testset "diagonal counting through active bound frames" begin # A single T occurrence in an active upper-bound frame should not combine # with the body occurrence of T. R1 = (Tuple{Union{Nothing, X}, T} where {X <: Tuple{T}}) where {T <: Real} @test Tuple{Nothing, Real} <: R1 @test Tuple{Tuple{Int}, Real} <: R1 @test Tuple{Tuple{Real}, Real} <: R1 @test Tuple{Tuple{Int}, Int} <: R1 # A bound that is syntactically diagonal should matter only when the X arm # is active. If it is active, abstract T should fail and concrete T should pass. R2 = (Tuple{Union{Nothing, X}, T} where {X <: Tuple{T, T}}) where {T <: Real} @test Tuple{Nothing, Real} <: R2 @test Tuple{Tuple{Int, Int}, Int} <: R2 @test !(Tuple{Tuple{Int, Real}, Real} <: R2) @test !(Tuple{Tuple{Real, Real}, Real} <: R2) # The bound itself has branch-dependent diagonality: # # Tuple{Union{Nothing, T}, T} # # is non-diagonal on the Tuple{Nothing, T} branch, but diagonal on the # Tuple{T, T} branch. R3 = (Tuple{Union{Nothing, X}, T} where {X <: Tuple{Union{Nothing, T}, T}}) where {T <: Real} @test Tuple{Nothing, Real} <: R3 @test Tuple{Tuple{Nothing, Real}, Real} <: R3 @test !(Tuple{Tuple{Int, Real}, Real} <: R3) @test Tuple{Tuple{Int, Int}, Int} <: R3 # Same branch-dependent bound shape, but with the union exposed at the top # level of the bound. R4 = (Tuple{X, T} where {X <: Union{Tuple{Nothing, T}, Tuple{T, T}}}) where {T <: Real} @test Tuple{Tuple{Nothing, Real}, Real} <: R4 @test !(Tuple{Tuple{Int, Real}, Real} <: R4) @test Tuple{Tuple{Int, Int}, Int} <: R4 # Overlapping bound arms: the existence of a successful non-diagonal arm # should be enough. The diagonal arm should not poison the whole bound. R5 = (Tuple{X, T} where {X <: Union{Tuple{Int, T}, Tuple{T, T}}}) where {T <: Real} @test Tuple{Tuple{Int, Real}, Real} <: R5 @test !(Tuple{Tuple{Bool, Real}, Real} <: R5) @test Tuple{Tuple{Bool, Bool}, Bool} <: R5 # Combination of an outer inactive X branch and overlapping bound arms. R6 = (Tuple{Union{Nothing, X}, T} where {X <: Union{Tuple{Int, T}, Tuple{T, T}}}) where {T <: Real} @test Tuple{Nothing, Real} <: R6 @test Tuple{Tuple{Int, Real}, Real} <: R6 @test !(Tuple{Tuple{Bool, Real}, Real} <: R6) @test Tuple{Tuple{Bool, Bool}, Bool} <: R6 end let S = ccall(:jl_new_structv, Any, (Any, Ptr{Cvoid}, UInt32), UnionAll, [TypeVar(:T), Any], 2), VS = TypeVar(:T), T = ccall(:jl_new_structv, Any, (Any, Ptr{Cvoid}, UInt32), UnionAll, [VS, VS], 2) # check (T where T) == (Any where T) # these types are not normally valid, but check them just to make sure subtyping is robust @test T <: S @test S <: T end # issue #20121 @test NTuple{170,Matrix{Int}} <: (Tuple{Vararg{Union{Vector{T},Matrix{T},Array{T,3}}}} where T) # Issue #12580 abstract type AbstractMyType12580{T} end struct MyType12580{T}<:AbstractMyType12580{T} end tpara(::Type{A}) where {A<:AbstractMyType12580} = tpara(supertype(A)) tpara(::Type{AbstractMyType12580{I}}) where {I} = I @test tpara(MyType12580{true}) # Issue #18348 f18348(::Type{T}, x) where {T<:Any} = 1 f18348(::Type{T}, x::T) where {T<:Any} = 2 @test length(methods(f18348, Tuple{Type{Any},Any})) == 1 # Issue #13165 @test Symmetric{Float64,Matrix{Float64}} <: LinearAlgebra.RealHermSymComplexHerm @test Hermitian{Float64,Matrix{Float64}} <: LinearAlgebra.RealHermSymComplexHerm @test Hermitian{ComplexF64,Matrix{ComplexF64}} <: LinearAlgebra.RealHermSymComplexHerm # Issue #12721 f12721(::T) where {T<:Type{Int}} = true @test_throws MethodError f12721(Float64) # implicit "covariant" type parameters: mutable struct TwoParams{S,T}; x::S; y::T; end @test TwoParams{<:Real,<:Number} == (TwoParams{S,T} where S<:Real where T<:Number) == (TwoParams{S,<:Number} where S<:Real) == (TwoParams{<:Real,T} where T<:Number) @test TwoParams(3,0im) isa TwoParams{<:Real,<:Number} @test TwoParams(3,"foo") isa TwoParams{<:Real} @test !(TwoParams(3im,0im) isa TwoParams{<:Real,<:Number}) @test !(TwoParams(3,"foo") isa TwoParams{<:Real,<:Number}) ftwoparams(::TwoParams) = 1 ftwoparams(::TwoParams{<:Real}) = 2 ftwoparams(::TwoParams{<:Real,<:Real}) = 3 @test ftwoparams(TwoParams('x',3)) == 1 @test ftwoparams(TwoParams(3,'x')) == 2 @test ftwoparams(TwoParams(3,4)) == 3 @test !([TwoParams(3,4)] isa Vector{TwoParams{<:Real,<:Real}}) @test TwoParams{<:Real,<:Real}[TwoParams(3,4)] isa Vector{TwoParams{<:Real,<:Real}} @test [TwoParams(3,4)] isa Vector{<:TwoParams{<:Real,<:Real}} @test [TwoParams(3,4)] isa (Vector{TwoParams{T,T}} where T<:Real) # implicit "contravariant" type parameters: @test TwoParams{>:Int,<:Number} == (TwoParams{S,T} where S>:Int where T<:Number) == (TwoParams{S,<:Number} where S>:Int) == (TwoParams{>:Int,T} where T<:Number) @test TwoParams(3,0im) isa TwoParams{>:Int,<:Number} @test TwoParams{Real,Complex}(3,0im) isa TwoParams{>:Int,<:Number} @test !(TwoParams(3.0,0im) isa TwoParams{>:Int,<:Number}) @test !(TwoParams(3,'x') isa TwoParams{>:Int,<:Number}) # supertype operator @test !(Int >: Integer) @test Integer >: Int # tolerate non-types in Tuples @test typeintersect(Tuple{0}, Tuple{T} where T) === Tuple{0} # TypeVars deduced as non-type constants (#20869) @testintersect(Tuple{Val{0}, Val{Val{N}}} where N, Tuple{Val{N}, Val{Val{N}}} where N, Tuple{Val{0},Val{Val{0}}}) @testintersect(Tuple{Val{N}, Val{Val{0}}} where N, Tuple{Val{N}, Val{Val{N}}} where N, Tuple{Val{0},Val{Val{0}}}) @testintersect(Tuple{Val{Val{0}}, Val{N}} where N, Tuple{Val{Val{N}}, Val{N}} where N, Tuple{Val{Val{0}},Val{0}}) @testintersect(Tuple{Val{Val{N}}, Val{0}} where N, Tuple{Val{Val{N}}, Val{N}} where N, Tuple{Val{Val{0}},Val{0}}) # a bunch of cases found by fuzzing let a = Tuple{Float64,T7} where T7, b = Tuple{S5,Tuple{S5}} where S5 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test I1 <: b @test I2 <: b end let a = Tuple{T1,T1} where T1, b = Tuple{Val{S2},S6} where S2 where S6 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test I1 <: b @test I2 <: b end let a = Val{Tuple{T1,T1}} where T1, b = Val{Tuple{Val{S2},S6}} where S2 where S6 @testintersect(a, b, Val{Tuple{Val{T},Val{T}}} where T) end let a = Tuple{Float64,T3,T4} where T4 where T3, b = Tuple{S2,Tuple{S3},S3} where S2 where S3 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test_broken I1 <: b @test_broken I2 <: b end let a = Tuple{T1,Tuple{T1}} where T1, b = Tuple{Float64,S3} where S3 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test I1 <: b @test I2 <: b end let a = Tuple{5,T4,T5} where T4 where T5, b = Tuple{S2,S3,Tuple{S3}} where S2 where S3 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test_broken I1 <: b @test_broken I2 <: b end let a = Tuple{T2,Tuple{T4,T2}} where T4 where T2, b = Tuple{Float64,Tuple{Tuple{S3},S3}} where S3 @test typeintersect(a, b) <: b end let a = Tuple{Tuple{T2,4},T6} where T2 where T6, b = Tuple{Tuple{S2,S3},Tuple{S2}} where S2 where S3 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test_broken I1 <: b @test_broken I2 <: b end let a = Tuple{T3,Int64,Tuple{T3}} where T3, b = Tuple{S3,S3,S4} where S4 where S3 @testintersect(a, b, Tuple{Int64, Int64, Tuple{Int64}}) end let a = Tuple{T1,Val{T2},T2} where T2 where T1, b = Tuple{Float64,S1,S2} where S2 where S1 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test_broken I1 <: a @test_broken I2 <: a @test I1 <: b @test I2 <: b end let a = Tuple{T1,Val{T2},T2} where T2 where T1, b = Tuple{Float64,S1,S2} where S2 where S1 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test_broken I1 <: a @test_broken I2 <: a @test I1 <: b @test I2 <: b end let a = Tuple{Float64,T1} where T1, b = Tuple{S1,Tuple{S1}} where S1 I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test I1 <: b @test I2 <: b end let a = Tuple{Val{T1},T2,T2} where T2 where T1, b = Tuple{Val{Tuple{S2}},S3,Float64} where S2 where S3 @testintersect(a, b, Tuple{Val{Tuple{S2}},Float64,Float64} where S2) end let a = Tuple{T1,T2,T2} where T1 where T2, b = Tuple{Val{S2},S2,Float64} where S2, x = Tuple{Val{Float64},Float64,Float64} I1 = typeintersect(a, b) I2 = typeintersect(b, a) @test x <: I1 @test x <: I2 @test I1 <: I2 @test I2 <: I1 @test I1 <: a @test I2 <: a @test_broken I1 <: b @test_broken I2 <: b end @testintersect(Val{Tuple{T1,Val{T2},Val{Int64},Tuple{Tuple{T3,5,Float64},T4,T2,T5}}} where T1 where T5 where T4 where T3 where T2, Val{Tuple{Tuple{S1,5,Float64},Val{S2},S3,Tuple{Tuple{Val{Float64},5,Float64},2,Float64,S4}}} where S2 where S3 where S1 where S4, Val{Tuple{Tuple{S1, 5, Float64}, Val{Float64}, Val{Int64}, Tuple{Tuple{Val{Float64}, 5, Float64}, 2, Float64, T5}}} where {T5, S1}) # issue #20992 abstract type A20992{T,D,d} end abstract type B20992{SV,T,D,d} <: A20992{T,D,d} end struct C20992{S,n,T,D,d} <: B20992{NTuple{n,S},T,D,d} end @testintersect(Tuple{A20992{R, D, d} where d where D, Int} where R, Tuple{C20992{S, n, T, D, d} where d where D where T where n where S, Any}, Tuple{C20992, Int}) # Issue #19414 let ex = try struct A19414 <: Base.AbstractSet end catch e; e end @test isa(ex, ErrorException) && ex.msg == "invalid subtyping in definition of A19414: supertype `Base.AbstractSet{T}` has unbound type parameters." end # issue #20103, OP and comments struct TT20103{X,Y} end f20103(::Type{TT20103{X,Y}},x::X,y::Y) where {X,Y} = 1 f20103(::Type{TT20103{X,X}},x::X) where {X} = 100 @testintersect(Type{NTuple{N,E}} where E where N, Type{NTuple{N,E} where N} where E, Union{}) let ints = (Int, Int32, UInt, UInt32) Ints = Union{ints...} vecs = [] for i = 2:4, t in ints push!(vecs, NTuple{i, t}) end Vecs = Union{vecs...} T = Type{Tuple{V, I}} where V <: Vecs where I <: Ints @testintersect(T, T, T) test(a::Type{Tuple{V, I}}) where {V <: Vecs, I <: Ints} = I end # issue #21191 let T1 = Val{Val{Val{Union{Int8,Int16,Int32,Int64,UInt8,UInt16}}}}, T2 = Val{Val{Val{Union{Int8,Int16,Int32,Int64,UInt8, S}}}} where S @test T1 <: T2 end # issue #21613 abstract type A21613{S <: Tuple} end struct B21613{S <: Tuple, L} <: A21613{S} data::NTuple{L,Float64} end @testintersect(Tuple{Type{B21613{Tuple{L},L}} where L, Any}, Tuple{Type{SA}, Tuple} where SA<:(A21613{S} where S<:Tuple), Tuple{Type{B21613{Tuple{L},L}} where L, Tuple}) # issue #22239 @testintersect(Val{Pair{T,T}} where T, Val{Pair{Int,T}} where T, Val{Pair{Int,Int}}) # issue #23024 @testintersect(Tuple{DataType, Any}, Tuple{Type{T}, Int} where T, Tuple{DataType, Int}) # issue #23430 @test [0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.; 0 0.] isa Matrix{Float64} @test !(Tuple{Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64, Int64,Float64,Int64,Float64,Int64,Float64,Int64,Float64} <: (Tuple{Vararg{T}} where T<:Number)) # part of issue #23327 let triangular(::Type{<:AbstractArray{T}}) where {T} = T triangular(::Type{<:AbstractArray}) = Any @test triangular(Vector{Vector{T}} where T) === Any end # issue #23908 @test Vector{Union{Int128, Int16, Int32, Int8}} <: Vector{Union{Int128, Int32, Int8, _1}} where _1 let A = Pair{Nothing, Pair{Vector{Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}}, Nothing}}, B = Pair{Nothing, Pair{Vector{Union{Int8, UInt128, UInt16, UInt32, UInt64, UInt8, _1}}, Nothing}} where _1 @test A <: B @test !(B <: A) end # issue #22688 let X = Ref{Tuple{Vector{Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}}}} @test !(X <: Ref{Tuple{Array{Union{Int8, UInt128, UInt16, UInt32, UInt64, UInt8, S}}}} where S) @test X <: Ref{Tuple{Vector{Union{Int8, UInt128, UInt16, UInt32, UInt64, UInt8, S}}}} where S end let X = Ref{Tuple{Vector{Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}}, Vector{Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}}}}, Y = Ref{Tuple{Vector{Union{Int8, UInt128, UInt16, UInt32, UInt64, UInt8, S}}, Vector{Union{Int8, UInt128, UInt16, UInt32, UInt64, UInt8, T}}}} where S where T @test X <: Y end # issue #23764 @test Tuple{Ref{Union{T,Int}} where {T}} <: Tuple{Ref{T}} where {T} @test Tuple{Ref{Union{T,Int}} where {T}} <: Tuple{Ref{T} where {T}} @test (Tuple{Ref{Union{T,Int}}} where T) <: Tuple{Ref{T}} where {T} @test (Tuple{Ref{Union{T,Int}}} where T) <: Tuple{Ref{T} where {T}} @test Tuple{Tuple{Tuple{R}} where R} <: Tuple{Tuple{S}} where S struct A23764{T, N, S} <: AbstractArray{Union{T, S}, N}; end @test Tuple{A23764{Int, 1, T} where T} <: Tuple{AbstractArray{T,N}} where {T,N} struct A23764_2{T, N, S} <: AbstractArray{Union{Ref{T}, S}, N}; end @test Tuple{A23764_2{T, 1, Nothing} where T} <: Tuple{AbstractArray{T,N}} where {T,N} @test Tuple{A23764_2{T, 1, Nothing} where T} <: Tuple{AbstractArray{T,N} where {T,N}} # issue #50716 @test !<:(Ref{Vector{Tuple{K}} where K}, Ref{<:Vector{K}} where K) # issue #26131 @test !(Vector{Vector{Number}} <: Vector{Union{Vector{Number}, Vector{S}}} where S<:Integer) # issue #24305 f24305(x) = [g24305(x) g24305(x) g24305(x) g24305(x); g24305(x) g24305(x) 0 0]; @test_throws UndefVarError f24305(1) f1_24305(x,y,z) = x*y-z^2-1 f2_24305(x,y,z) = x*y*z+y^2-x^2-2 f3_24305(x,y,z) = exp(x)+z-exp(y)-3 Fun_24305(x) = [ f1_24305(x[1],x[2],x[3]); f2_24305(x[1],x[2],x[3]); f3_24305(x[1],x[2],x[3]) ] Jac_24305(x) = [ x[2] x[1] -2*x[3] ; x[2]*x[3]-2x[1] x[1]*x[3]+2x[2] x[1]*x[2] ; exp(x[1]) -exp(x[2]) 1 ] x_24305 = fill(1.,3) for it = 1:5 h = - \(Jac_24305(x_24305), Fun_24305(x_24305)) global x_24305 = x_24305 + h end @test round.(x_24305, digits=2) == [1.78, 1.42, 1.24] # PR #24399 let (t, e) = intersection_env(Tuple{Union{Int,Int8}}, Tuple{T} where T) @test e[1] isa Core.SimpleVector && e[1][1] isa TypeVar end # issue #25430 @test Vector{Tuple{Any}}() isa Vector{Tuple{>:Int}} @test Vector{Tuple{>:Int}}() isa Vector{Tuple{Any}} @test Vector{Tuple{Any}} == Vector{Tuple{>:Int}} @test Vector{Vector{Tuple{Any}}} == Vector{Vector{Tuple{>:Int}}} f25430(t::Vector{Tuple{Any}}) = true g25430(t::Vector{Tuple{>:Int}}) = true @test f25430(Vector{Tuple{>:Int}}()) @test g25430(Vector{Tuple{Any}}()) @testintersect(Vector{Tuple{>:Int}}, Vector{Tuple{Any}}, Vector{Tuple{Any}}) @testintersect(Vector{Vector{Tuple{>:Int}}}, Vector{Vector{Tuple{Any}}}, Vector{Vector{Tuple{Any}}}) # issue #24521 g24521(::T, ::T) where {T} = T @test_throws MethodError g24521(Tuple{Any}, Tuple{T} where T) @test g24521(Vector, Matrix) == UnionAll @test [Tuple{Vararg{Int64}}, Tuple{Vararg{Int64,N}} where N] isa Vector{Type} f24521(::Type{T}, ::Type{T}) where {T} = T @test f24521(Tuple{Any}, Tuple{T} where T) == Tuple{Any} @test f24521(Tuple{Vararg{Int64}}, Tuple{Vararg{Int64,N}} where N) == Tuple{Vararg{Int64,N}} where N # issue #26654 @test !(Ref{Union{Int64, Ref{Number}}} <: Ref{Union{Ref{T}, T}} where T) @test !(Ref{Union{Int64, Val{Number}}} <: Ref{Union{Val{T}, T}} where T) @test !(Ref{Union{Ref{Number}, Int64}} <: Ref{Union{Ref{T}, T}} where T) @test !(Ref{Union{Val{Number}, Int64}} <: Ref{Union{Val{T}, T}} where T) @test !(Val{Ref{Union{Int64, Ref{Number}}}} <: Val{S} where {S<:Ref{Union{Ref{T}, T}} where T}) @test !(Tuple{Ref{Union{Int64, Ref{Number}}}} <: Tuple{S} where {S<:Ref{Union{Ref{T}, T}} where T}) # issue #26180 @test !(Ref{Union{Ref{Int64}, Ref{Number}}} <: Ref{Ref{T}} where T) @test !(Ref{Union{Ref{Int64}, Ref{Number}}} <: Ref{Union{Ref{T}, Ref{T}}} where T) # issue #25240, #26405 f26405(::Type{T}) where {T<:Union{Integer, Missing}} = T @test f26405(Union{Missing, Int}) == Union{Missing, Int} # issue #24748 abstract type Foo24748{T1,T2,T3} end @test !(Foo24748{Int,Float64,Ref{Integer}} <: Foo24748{<:T,<:T,Ref{T}} where T) # issue #26129 @test !(Tuple{Type{Union{Missing, Float64}}, Type{Vector{Missing}}} <: Tuple{Type{T}, Type{Vector{T}}} where T) @test !(Tuple{Type{Union{Missing, Float64}}, Type{Vector{Float64}}} <: Tuple{Type{T}, Type{Vector{T}}} where T) @test [[1],[missing]] isa Vector{Vector} @test [[missing],[1]] isa Vector{Vector} # issue #26453 @test (Tuple{A,A,Number} where A>:Number) <: Tuple{T,T,S} where T>:S where S @test (Tuple{T,T} where {S,T>:S}) == (Tuple{T,T} where {S,T>:S}) f26453(x::T,y::T) where {S,T>:S} = 0 @test f26453(1,2) == 0 @test f26453(1,"") == 0 g26453(x::T,y::T) where {S,T>:S} = T @test_throws UndefVarError(:T, :static_parameter) g26453(1,1) @test issub_strict((Tuple{T,T} where T), (Tuple{T,T} where {S,T>:S})) # issue #27632 @test !(Tuple{Array{Int,0}, Int, Vararg{Int}} <: Tuple{AbstractArray{T,N}, Vararg{Int,N}} where {T, N}) @test !(Tuple{Array{Int,0}, Int, Vararg{Int}} <: Tuple{AbstractArray{T,N}, Vararg{Any,N}} where {T, N}) @test !(Tuple{Array{Int,0}, Vararg{Any}} <: Tuple{AbstractArray{T,N}, Vararg{Any,N}} where {T, N}) @test Tuple{Array{Int,0},} <: Tuple{AbstractArray{T,N}, Vararg{Any,N}} where {T, N} @test !(Tuple{Array{Int,0}, Any} <: Tuple{AbstractArray{T,N}, Vararg{Any,N}} where {T, N}) # issue #26827 @test typeintersect(Union{Int8,Int16,Int32}, Union{Int8,Int16,Int64}) == Union{Int8, Int16} @test typeintersect(Union{Int8,Int16,Float64}, Integer) == Union{Int8, Int16} @test typeintersect(Integer, Union{Int8,Int16,Float64}) == Union{Int8, Int16} @test typeintersect(Tuple{Ref{Int},Any}, Tuple{Ref{T},Union{Val{N}, Array{Float32,N}}} where {T,N}) == Tuple{Ref{Int},Union{Val{N}, Array{Float32,N}}} where N @test typeintersect(Tuple{Ref{T},Union{Val{N}, Array{Float32,N}}} where {T,N}, Tuple{Ref{Int},Any}) == Tuple{Ref{Int},Union{Val{N}, Array{Float32,N}}} where N # issue #28256 @test Pair{(:a,), Pair{(:a,),Tuple{Int}}} isa Type{Pair{names,T}} where {names, T<:Pair{names,<:Tuple}} @test Type{Pair{(:a,), Pair{(:a,),Tuple{Int}}}} <: Type{Pair{names,T}} where {names, T<:Pair{names,<:Tuple}} struct A28256{names, T<:NamedTuple{names, <:Tuple}} x::T end @test A28256{(:a,), NamedTuple{(:a,),Tuple{Int}}}((a=1,)) isa A28256 # issue #29468 @testintersect(Tuple{Vararg{Val{N}, N}} where N, Tuple{Val{2}, Vararg{Val{2}}}, Tuple{Val{2}, Val{2}}) @testintersect(Tuple{Vararg{Val{N}, N}} where N, Tuple{Val{3}, Vararg{Val{3}}}, Tuple{Val{3}, Val{3}, Val{3}}) @testintersect(Tuple{Vararg{Val{N}, N}} where N, Tuple{Val{1}, Vararg{Val{2}}}, Tuple{Val{1}}) @testintersect(Tuple{Vararg{Val{N}, N}} where N, Tuple{Val{2}, Vararg{Val{3}}}, Union{}) # issue #25752 @testintersect(Base.RefValue, Ref{Union{Int,T}} where T, Base.RefValue{Union{Int,T}} where T) # issue #29269 @testintersect((Tuple{Int, Array{T}} where T), (Tuple{Any, Vector{Union{Missing,T}}} where T), (Tuple{Int, Vector{Union{Missing,T}}} where T)) @testintersect((Tuple{Int, Array{T}} where T), (Tuple{Any, Vector{Union{Missing,Nothing,T}}} where T), (Tuple{Int, Vector{Union{Missing,Nothing,T}}} where T)) # issue #32582 let A = Tuple{Any, Type{Union{Nothing, Int64}}}, B = Tuple{T, Type{Union{Nothing, T}}} where T, I = typeintersect(A, B), J = typeintersect(B, A) # TODO: improve precision @test I >: Tuple{Int64,Type{Union{Nothing, Int64}}} @test J >: Tuple{Int64,Type{Union{Nothing, Int64}}} end @testintersect(Union{Vector{T},Matrix{T}} where T<:Union{Float32,Float64}, Union{AbstractMatrix{Float32},AbstractVector{Float32}}, Union{Matrix{Float32}, Vector{Float32}}) let A = Tuple{Type{Union{Missing,T}},Any} where T, B = Tuple{Type{Union{Nothing,T}},Any} where T I = typeintersect(A, B) J = typeintersect(B, A) @test I >: Tuple{Type{Union{Nothing,Missing,T}}, Any} where T @test J >: Tuple{Type{Union{Nothing,Missing,T}}, Any} where T end # issue #29955 struct M29955{T, TV<:AbstractVector{T}} end @testintersect(M29955, M29955{<:Any,TV} where TV>:Vector{Float64}, M29955{Float64,TV} where Vector{Float64}<:TV<:AbstractVector{Float64}) struct A29955{T, TV<:AbstractVector{T}, TModel<:M29955{T,TV}} end @testintersect(Tuple{Type{A29955{Float64,Vector{Float64},_1}} where _1, Any}, Tuple{Type{A29955{T,TV,TM}}, TM} where {T,TV<:AbstractVector{T},TM<:M29955{T,TV}}, Tuple{Type{A29955{Float64,Vector{Float64},TM}}, M29955{Float64,Vector{Float64}}} where TM<:M29955{Float64,Vector{Float64}}) let M = M29955{T,Vector{Float64}} where T @test M == (M29955{T,Vector{Float64}} where T) @test M{Float64} == M29955{Float64,Vector{Float64}} @test_throws TypeError M{Float32} @test_throws TypeError M{Real} end # issue #30122 @testintersect(Tuple{Pair{Int64,2}, NTuple}, Tuple{Pair{F,N},Tuple{Vararg{F,N}}} where N where F, Tuple{Pair{Int64,2}, Tuple{Int64,Int64}}) # issue #30335 @testintersect(Tuple{Any,Rational{Int},Int}, Tuple{LT,R,I} where LT<:Union{I, R} where R<:Rational{I} where I<:Integer, Tuple{LT,Rational{Int},Int} where LT<:Union{Rational{Int},Int}) @testintersect(Tuple{Any,Tuple{Int},Int}, Tuple{LT,R,I} where LT<:Union{I, R} where R<:Tuple{I} where I<:Integer, Tuple{LT,Tuple{Int},Int} where LT<:Union{Tuple{Int},Int}) let U = Tuple{Union{LT, LT1},Union{R, R1},Int} where LT1<:R1 where R1<:Tuple{Int} where LT<:Int where R<:Tuple{Int}, U2 = Union{Tuple{LT,R,Int} where LT<:Int where R<:Tuple{Int}, Tuple{LT,R,Int} where LT<:R where R<:Tuple{Int}}, V = Tuple{Union{Tuple{Int},Int},Tuple{Int},Int}, V2 = Tuple{L,Tuple{Int},Int} where L<:Union{Tuple{Int},Int} @test U == U2 @test U == V @test U == V2 @test V == V2 @test U2 == V @test U2 == V2 end # issue #31082 and #30741 @test typeintersect(Tuple{T, Ref{T}, T} where T, Tuple{Ref{S}, S, S} where S) != Union{} # TODO: improve this bound @testintersect(Tuple{Pair{B,C},Union{C,Pair{B,C}},Union{B,Real}} where {B,C}, Tuple{Pair{B,C},C,C} where {B,C}, Tuple{Pair{B,C}, Union{Pair{B,C},C},Union{Real,B}} where {B,C}) f31082(::Pair{B, C}, ::Union{C, Pair{B, C}}, ::Union{B, Real}) where {B, C} = 0 f31082(::Pair{B, C}, ::C, ::C) where {B, C} = 1 @test f31082(""=>1, 2, 3) == 1 @test f31082(""=>1, 2, "") == 0 @test f31082(""=>1, 2, 3.0) == 0 @test f31082(Pair{Any,Any}(1,2), 1, 2) == 1 @test f31082(Pair{Any,Any}(1,2), Pair{Any,Any}(1,2), 2) == 1 @test f31082(Pair{Any,Any}(1,2), 1=>2, 2.0) == 1 # issue #31115 @testintersect(Tuple{Ref{Z} where Z<:(Ref{Y} where Y<:Tuple{<:B}), Int} where B, Tuple{Ref{Z} where Z<:(Ref{Y} where Y<:Tuple{ B}), Any} where B<:AbstractMatrix, Tuple{Ref{Z} where Z<:(Ref{Y} where Y<:Tuple{ B}), Int} where B<:AbstractMatrix) # issue #31190 @test (Tuple{T} where T <: Union{Int,Bool}) <: Union{Tuple{Int}, Tuple{Bool}} # issue #31439 @testintersect(Tuple{Type{Val{T}},Integer,T} where T, Tuple{Type,Int,Any}, Tuple{Type{Val{T}},Int,T} where T) @testintersect(Tuple{Type{Val{T}},Integer,T} where T, Tuple{Type,Int,Integer}, Tuple{Type{Val{T}},Int,Integer} where T) @testintersect(Tuple{Type{Val{T}},Integer,T} where T>:Integer, Tuple{Type,Int,Integer}, Tuple{Type{Val{T}},Int,Integer} where T>:Integer) @testintersect(Tuple{Type{Val{T}},Integer,T} where T>:Integer, Tuple{Type,Int,Int}, Tuple{Type{Val{T}},Int,Int} where T>:Integer) # issue #31496 CovType{T} = Union{AbstractMatrix{T}, Vector{UpperTriangular{T,Matrix{T}}}} @testintersect(Pair{<:Any, <:AbstractMatrix}, Pair{T, <:CovType{T}} where T<:AbstractFloat, Pair{T,S} where S<:AbstractMatrix{T} where T<:AbstractFloat) # issue #31703 @testintersect(Pair{<:Any, Ref{Tuple{Ref{Ref{Tuple{Int}}},Ref{Float64}}}}, Pair{T, S} where S<:(Ref{A} where A<:(Tuple{C,Ref{T}} where C<:(Ref{D} where D<:(Ref{E} where E<:Tuple{FF}) where FF<:B)) where B) where T, Pair{Float64, Ref{Tuple{Ref{Ref{Tuple{Int}}},Ref{Float64}}}}) module I31703 using Test, LinearAlgebra import Base: OneTo, Slice struct BandedMatrix{T, CONTAINER, RAXIS} end struct Ones{T, N, Axes} end const RestrictionMatrix = BandedMatrix{<:Int, <:Ones} struct Applied{Style, Args<:Tuple} end const Mul = Applied{Style,Factors} where Factors<:Tuple where Style const RestrictedBasis{B} = Mul{<:Any,<:Tuple{B, <:RestrictionMatrix}} struct ApplyQuasiArray{T, N, App<:Applied} end const MulQuasiArray = ApplyQuasiArray{T,N,MUL} where MUL<:(Applied{Style,Factors} where Factors<:Tuple where Style) where N where T const RestrictedQuasiArray{T,N,B} = MulQuasiArray{T,N,<:RestrictedBasis{B}} const BasisOrRestricted{B} = Union{B,RestrictedBasis{<:B},<:RestrictedQuasiArray{<:Any,<:Any,<:B}} struct QuasiAdjoint{T,S} end const AdjointRestrictedBasis{B} = Mul{<:Any,<:Tuple{<:Adjoint{<:Any,<:RestrictionMatrix}, <:QuasiAdjoint{<:Any,B}}} const AdjointRestrictedQuasiArray{T,N,B} = MulQuasiArray{T,N,<:AdjointRestrictedBasis{B}} const AdjointBasisOrRestricted{B} = Union{<:QuasiAdjoint{<:Any,B},AdjointRestrictedBasis{<:B},<:AdjointRestrictedQuasiArray{<:Any,<:Any,<:B}} const RadialOperator{T,B,M<:AbstractMatrix{T}} = Mul{<:Any,<:Tuple{<:BasisOrRestricted{B},M,<:AdjointBasisOrRestricted{B}}} const HFPotentialOperator{T,B} = RadialOperator{T,B,Diagonal{T,Vector{T}}} struct HFPotential{kind,T,B,RO<:HFPotentialOperator{T,B},P<:Integer} end T = HFPotential{_A,Float64,Any,Applied{Int,Tuple{ApplyQuasiArray{Float64,2,Applied{Int,Tuple{Any,BandedMatrix{Int,Ones{Int,2,Tuple{OneTo{Int},OneTo{Int}}},OneTo{Int}}}}},Diagonal{Float64,Vector{Float64}},ApplyQuasiArray{Float64,2,Applied{Int,Tuple{Adjoint{Int,BandedMatrix{Int,Ones{Int,2,Tuple{OneTo{Int},OneTo{Int}}},OneTo{Int}}},QuasiAdjoint{Float64,Any}}}}}},_B} where _B where _A let A = typeintersect(HFPotential, T), B = typeintersect(T, HFPotential) @test A == B == HFPotential{kind,Float64,Any,Applied{Int,Tuple{ApplyQuasiArray{Float64,2,Applied{Int,Tuple{Any,BandedMatrix{Int,Ones{Int,2,Tuple{OneTo{Int},OneTo{Int}}},OneTo{Int}}}}},Diagonal{Float64,Vector{Float64}},ApplyQuasiArray{Float64,2,Applied{Int,Tuple{Adjoint{Int,BandedMatrix{Int,Ones{Int,2,Tuple{OneTo{Int},OneTo{Int}}},OneTo{Int}}},QuasiAdjoint{Float64,Any}}}}}},P} where P<:Integer where kind end end # issue #26083 @testintersect(Base.RefValue{<:Tuple}, Ref{Tuple{M}} where M, Base.RefValue{Tuple{M}} where M) # issue #31899 struct SA{N,L} end @testintersect(Tuple{Type{SA{Int, L} where L}, Type{SA{Int, Int8}}}, Tuple{Type{<:SA{N, L}}, Type{<:SA{N, L}}} where {N,L}, Union{}) @testintersect(Tuple{Type{SA{2, L} where L}, Type{SA{2, 16}}}, Tuple{Type{<:SA{N, L}}, Type{<:SA{N, L}}} where {L,N}, Union{}) @testintersect(Tuple{Type{SA{2, L} where L}, Type{SA{2, 16}}}, Tuple{Type{<:SA{N, L}}, Type{<:SA{N, L}}} where {N,L}, Union{}) @testintersect(Tuple{Type{SA{2, L}}, Type{SA{2, L}}} where L, Tuple{Type{<:SA{N, L}}, Type{<:SA{N, L}}} where {N,L}, Tuple{Type{SA{2, L}}, Type{SA{2, L}}} where L) @testintersect(Tuple{Type{SA{2, L}}, Type{SA{2, 16}}} where L, Tuple{Type{<:SA{N, L}}, Type{<:SA{N, L}}} where {N,L}, Tuple{Type{SA{2, 16}}, Type{SA{2, 16}}}) # issue #31993 @testintersect(Tuple{Type{<:AbstractVector{T}}, Int} where T, Tuple{Type{Vector}, Any}, Union{}) @testintersect(Tuple{Type{<:AbstractVector{T}}, Int} where T, Tuple{Type{Vector{T} where Int<:T<:Int}, Any}, Tuple{Type{Vector{Int}}, Int}) let X = LinearAlgebra.Symmetric{T, S} where S<:(AbstractMatrix{U} where U<:T) where T, Y = Union{LinearAlgebra.Hermitian{T, S} where S<:(AbstractMatrix{U} where U<:T) where T, LinearAlgebra.Symmetric{T, S} where S<:(AbstractMatrix{U} where U<:T) where T} @test X <: Y end # Various nasty varargs let T1 = Tuple{Int, Tuple{T}, Vararg{T, 3}} where T <: Int, T2 = Tuple{Int, Any, Any, Any, Integer}, T3 = Tuple{Int, Any, Any, Any, Integer, Vararg{Integer}} @test issub_strict(T1, T2) @test issub_strict(T2, T3) @test issub_strict(T1, T3) end let A = Tuple{Float64, Vararg{Int64, 2}}, B1 = Tuple{Float64, Vararg{T, 2}} where T <: Int64, B2 = Tuple{Float64, T, T} where T <: Int64, C = Tuple{Float64, Any, Vararg{Integer}} @test A == B1 == B2 @test issub_strict(A, C) @test issub_strict(B1, C) @test issub_strict(B2, C) end let B = Tuple{Vararg{Val{N}, N}} where N, C = Tuple{Val{2}, Val{2}} @test issub(C, B) end @test isequal_type(Tuple{T, Vararg{T, 2}} where T<:Real, Tuple{Vararg{T, 3}} where T<: Real) @test !issub(Tuple{Vararg{T, 3}} where T<:Real, Tuple{Any, Any, Any, Any, Vararg{Any}}) @test !issub(Tuple{Vararg{T, 3}} where T<:Real, Tuple{Any, Any, Any, Any, Vararg{Any, N}} where N) @test issub_strict(Ref{Tuple{Int, Vararg{Int, N}}} where N, Ref{Tuple{Vararg{Int, N}}} where N) let T31805 = Tuple{Type{Tuple{}}, Tuple{Vararg{Int8, A}}} where A, S31805 = Tuple{Type{Tuple{Vararg{Int32, A}}}, Tuple{Vararg{Int16, A}}} where A @test !issub(T31805, S31805) end @testintersect( Tuple{Array{Tuple{Vararg{Int64,N}},N},Tuple{Vararg{Vector{Int64},N}}} where N, Tuple{Vector{Tuple{Int64}}, Tuple}, Tuple{Vector{Tuple{Int64}},Tuple{Vector{Int64}}}) @test !isequal_type(Tuple{Int, Vararg{T, 3}} where T<:Real, Tuple{Int, Real, Vararg{T, 2}} where T<:Integer) @test !isequal_type(Tuple{Tuple{Vararg{Int}},Tuple{Vararg{Int}}}, Tuple{Tuple{Vararg{Int, N}}, Tuple{Vararg{Int, N}}} where N) let (_, E) = intersection_env(Tuple{Tuple{Vararg{Int}}}, Tuple{Tuple{Vararg{Int,N}}} where N) @test !isa(E[1], Type) end # this is a timing test, so it would fail on debug builds #let T = Type{Tuple{(Union{Int, Nothing} for i = 1:23)..., Union{String, Nothing}}}, # S = Type{T} where T<:Tuple{E, Vararg{E}} where E # @test @elapsed (@test T != S) < 5 #end # issue #32386 @testintersect(Type{S} where S<:(Vector{Pair{_A,N} where N} where _A), Type{Vector{T}} where T, Type{Vector{Pair{_A,N} where N}} where _A) # pr #49049 @testintersect(Tuple{Type{Pair{T, A} where {T, A<:Array{T}}}, Int, Any}, Tuple{Type{F}, Any, Int} where {F<:(Pair{T, A} where {T, A<:Array{T}})}, Tuple{Type{Pair{T, A} where {T, A<:(Array{T})}}, Int, Int}) @testintersect(Type{Ref{Union{Int, Tuple{S,S} where S<:T}}} where T, Type{F} where F<:(Base.RefValue{Union{Int, Tuple{S,S} where S<:T}} where T), Union{}) # issue #32488 struct S32488{S <: Tuple, T, N, L} data::NTuple{L,T} end @testintersect(Tuple{Type{T} where T<:(S32488{Tuple{_A}, Int64, 1, _A} where _A), Tuple{Vararg{Int64, D}} where D}, Tuple{Type{S32488{S, T, N, L}}, Tuple{Vararg{T, L}}} where L where N where T where S, Tuple{Type{S32488{Tuple{L},Int64,1,L}},Tuple{Vararg{Int64,L}}} where L) # issue #32703 struct Str{C} <: AbstractString end struct CSE{X} end const UTF16CSE = CSE{1} const UTF16Str = Str{UTF16CSE} const ASCIIStr = Str{CSE{2}} c32703(::Type{<:Str{UTF16CSE}}, str::AbstractString) = 42 c32703(::Type{<:Str{C}}, str::Str{C}) where {C<:CSE} = str @testintersect(Tuple{Type{UTF16Str},ASCIIStr}, Tuple{Type{<:Str{C}}, Str{C}} where {C<:CSE}, Union{}) @test c32703(UTF16Str, ASCIIStr()) == 42 @testintersect(Tuple{Vector{Vector{Float32}},Matrix,Matrix}, Tuple{Vector{V},Matrix{Int},Matrix{S}} where {S, V<:AbstractVector{S}}, Tuple{Vector{Vector{Float32}},Matrix{Int},Matrix{Float32}}) @testintersect(Tuple{Pair{Int, DataType}, Any}, Tuple{Pair{A, B} where B<:Type, Int} where A, Tuple{Pair{Int, DataType}, Int}) # issue #33337 @test !issub(Tuple{Type{T}, T} where T<:NTuple{30, Union{Nothing, Ref}}, Tuple{Type{Tuple{Vararg{V}}}, Tuple{Vararg{V}}} where V) @test issub(Tuple{Type{Any}, NTuple{4,Union{Int,Nothing}}}, Tuple{Type{V}, Tuple{Vararg{V}}} where V) # issue #26065 t26065 = Ref{Tuple{T,Ref{Union{Ref{Tuple{Ref{Union{Ref{Ref{Tuple{Ref{Tuple{Union{Tuple{Ref{Ref{T}},T}, T},T}},T}}}, T}},T}}, Ref{T}, T}}}} where T s26065 = Ref{Tuple{T,Ref{Union{Ref{Tuple{Ref{Union{Ref{Ref{Tuple{Ref{Tuple{Union{Tuple{Ref{Ref{T}},T}, T},T}},T}}}, T}},T}}, Ref{T}, T}}}} where T @test t26065 <: s26065 # issue #33894 @testintersect(Tuple{Tuple{Vararg{Any,T}},:N} where T, Tuple{Tuple{Vararg{Any,T}},T} where T, Union{}) @testintersect(Tuple{Int,Vararg{Any,T}} where T, Tuple{T,Vararg{Any,T}} where T, Union{}) @testintersect(Tuple{:N,Vararg{Any,T}} where T, Tuple{T,Vararg{Any,T}} where T, Union{}) @test !issub(Tuple{Type{T}, T} where T<:Tuple{String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}, String, Union{Base.Regex, AbstractChar, AbstractString}}, Tuple{Type{Tuple{Vararg{V}}}, Tuple{Vararg{V}}} where V) # issue 36100 @test Pair{(:a, :b), Tuple{Missing, Vararg{Union{},N}} where N} === Pair{(:a, :b), Tuple{Missing, Vararg{Union{},N}} where N} != Pair{(:a, :b), Tuple{Missing, Vararg{Union{}}}} === Pair{(:a, :b), Tuple{Missing}} @test Val{Tuple{Missing, Vararg{Union{},N}} where N} === Val{Tuple{Missing, Vararg{Union{},N}} where N} != Val{Tuple{Missing, Vararg{Union{}}}} === Val{Tuple{Missing}} # issue #36869 struct F36869{T, V} <: AbstractVector{Union{T, V}} end @testintersect(Tuple{Type{T}, AbstractVector{T}} where T, Tuple{Union, F36869{Int64, Missing}}, Tuple{Union, F36869{Int64, Missing}}) # issue #37180 @test !(typeintersect(Tuple{AbstractArray{T}, VecOrMat{T}} where T, Tuple{Array, Any}).body.parameters[1] isa Union) # issue #37255 @test Type{Union{}} == Type{T} where {Union{}<:T<:Union{}} # issue #38081 struct AlmostLU{T, S<:AbstractMatrix{T}} end @testintersect(Tuple{AlmostLU, Vector{T}} where T, Tuple{AlmostLU{S, X} where X<:Matrix, Vector{S}} where S<:Union{Float32, Float64}, Tuple{AlmostLU{T, X} where X<:Matrix{T}, Vector{T}} where T<:Union{Float32, Float64}) # issue #22787 @testintersect(Tuple{Type{Q}, Q, Ref{Q}} where Q<:Ref, Tuple{Type{S}, Union{Ref{S}, Ref{R}}, R} where R where S, Tuple{Type{Q}, Union{Ref{Q}, Ref{R}}, Ref{Q}} where {Q<:Ref, R}) # likely suboptimal let t = typeintersect(Tuple{Type{T}, T, Ref{T}} where T, Tuple{Type{S}, Ref{S}, S} where S) @test_broken t == Tuple{Type{T}, Ref{T}, Ref{T}} where T>:Ref @test t == Tuple{Type{T}, Ref{T}, Ref{T}} where T end # issue #38279 t = typeintersect(Tuple{<:Array{T, N}, Val{T}} where {T<:Real, N}, Tuple{<:Array{T, N}, Val{<:AbstractString}} where {T<:Real, N}) @test t == Tuple{<:Array{Union{}, N}, Val{Union{}}} where N # issue #36951 @testintersect(Type{T} where T>:Missing, Type{Some{T}} where T, Union{}) # issue #38423 let Either{L, R} = Union{Ref{L}, Val{R}} A = Tuple{Type{Ref{L}}, Type{Either{L, <:Any}}} where L B = Tuple{Type{Ref{L2}}, Type{Either{L1, R}}} where {L1, R, L2 <: L1} I = typeintersect(A, B) @test I != Union{} @test_broken I <: A @test_broken I <: B end # issue #36804 let Either{L, R} = Union{Some{L}, Ref{R}} f(::Type{Either{L2, R}}, ::Type{Either{L1, R}}) where {L1, R, L2 <: L1} = Either{L1, R} f(::Type{Either{L, R1}}, ::Type{Either{L, R2}}) where {L, R1, R2 <: R1} = Either{L, R1} @test f(Either{Int,Real}, Either{Int,Float32}) == Either{Int,Real} end # issue #36544 let A = Tuple{T, Ref{T}, T} where {T}, B = Tuple{T, T, Ref{T}} where {T} I = typeintersect(A, B) @test I != Union{} @test_broken I <: A @test_broken I <: B end # issue #34170 let A = Tuple{Type{T} where T<:Ref, Ref, Union{T, Union{Ref{T}, T}} where T<:Ref}, B = Tuple{Type{T}, Ref{T}, Union{Int, Ref{T}, T}} where T # this was a case where <: disagreed with === (due to a badly-normalized type) I = _type_intersect(B, A) @test_broken I == Union{Tuple{Type{T}, Ref{T}, Ref{T}} where T<:Ref, Tuple{Type{T}, Ref{T}, T} where T<:Ref} @test I == _type_intersect(B, A) == Tuple{Type{T}, Ref{T}, Ref} where T<:Ref I = typeintersect(B, A) @test_broken I == Tuple{Type{T}, Ref{T}, Union{Ref{T}, T}} where T<:Ref @test I == typeintersect(B, A) <: Tuple{Type{T}, Ref{T}, Ref} where T<:Ref I = _type_intersect(A, B) @test !Base.has_free_typevars(I) J = Tuple{Type{T1}, Ref{T1}, Ref} where {T, T1<:Union{Ref, Ref{T}}} @test I == _type_intersect(A, B) == J @test_broken I == Tuple{Type{T}, Ref{T}, T1} where {T<:Ref, T1<:Union{T, Ref{T}}} # a better result, == to the result with arguments switched I = typeintersect(A, B) @test !Base.has_free_typevars(I) J = Tuple{Type{T1}, Ref{T1}, Ref} where {T, T1<:Union{Ref, Ref{T}}} @test I == typeintersect(A, B) == J end # issue #39218 let A = Int, B = String, U = Union{A, B} @test issub_strict(Union{Tuple{A, A}, Tuple{B, B}}, Tuple{U, U}) @test issub_strict(Union{Tuple{A, A}, Tuple{B, B}}, Tuple{Union{A, B}, Union{A, B}}) end struct A39218 end struct B39218 end const AB39218 = Union{A39218,B39218} f39218(::T, ::T) where {T<:AB39218} = false g39218(a, b) = (@nospecialize; if a isa AB39218 && b isa AB39218; f39218(a, b); end;) @test g39218(A39218(), A39218()) === false @test_throws MethodError g39218(A39218(), B39218()) # issue #39521 (updated for #33136: the `Type` slot has `UnionAll`-tagged # members, the `DataType` slots do not, so no concrete `B` covers all slots) @test !(Tuple{Type{Tuple{A}} where A, DataType, DataType} <: Tuple{Vararg{B}} where B) @test !(Tuple{DataType, Type{Tuple{A}} where A, DataType} <: Tuple{Vararg{B}} where B) let A = Tuple{Type{<:Union{Number, T}}, Ref{T}} where T, B = Tuple{Type{<:Union{Number, T}}, Ref{T}} where T # TODO: these are caught by the egal check, but the core algorithm gets them wrong @test A == B @test A <: B end # issue #39698 @testintersect(Type{T} where T<:(AbstractArray{I}) where I<:(Base.IteratorsMD.CartesianIndex), Type{S} where S<:(Base.IteratorsMD.CartesianIndices{A, B} where B<:Tuple{Vararg{Any, A}} where A), Type{S} where {N, S<:(Base.IteratorsMD.CartesianIndices{N, B} where B<:Tuple{Vararg{Any, N}})}) # issue #39948 @testintersect(Tuple{Vector{Pair{T, JT} where JT<:Ref{T}} where T, Vector}, Tuple{Vararg{Vector{T}}} where T, Tuple{Vector{Pair{T, JT} where JT<:Ref{T}}, Vector{Pair{T, JT} where JT<:Ref{T}}} where T) # issue #8915 struct D8915{T<:Union{Float32,Float64}} D8915{T}(a) where {T} = 1 D8915{T}(a::Int) where {T} = 2 end @test D8915{Float64}(1) == 2 @test D8915{Float64}(1.0) == 1 # issue #18985 f18985(x::T, y...) where {T<:Union{Int32,Int64}} = (length(y), f18985(y[1], y[2:end]...)...) f18985(x::T) where {T<:Union{Int32,Int64}} = 100 @test f18985(1, 2, 3) == (2, 1, 100) # issue #40048 let A = Tuple{Ref{T}, Vararg{T}} where T, B = Tuple{Ref{U}, Union{Ref{S}, Ref{U}, Int}, Union{Ref{S}, S}} where S where U, C = Tuple{Ref{U}, Union{Ref{S}, Ref{U}, Ref{W}}, Union{Ref{S}, W, V}} where V<:AbstractArray where W where S where U I = typeintersect(A, B) Ts = (Tuple{Ref{Int}, Int, Int}, Tuple{Ref{Ref{Int}}, Ref{Int}, Ref{Int}}) @test I != Union{} @test_broken I <: A @test I <: B for T in Ts if T <: A && T <: B @test T <: I end end J = typeintersect(A, C) @test J != Union{} @test_broken J <: A @test J <: C for T in Ts if T <: A && T <: C @test T <: J end end end let A = Tuple{Dict{I,T}, I, T} where T where I, B = Tuple{AbstractDict{I,T}, T, I} where T where I, I = typeintersect(A, B) # TODO: we should probably have something approaching I == T here, # though note something more complex is needed since the intersection must also include types such as; # Tuple{Dict{Integer,Any}, Integer, Int} @test_broken I <: A && I <: B @test I == typeintersect(B, A) == Tuple{Dict{I, T}, Any, Any} where {I, T} end let A = Tuple{UnionAll, Vector{Any}}, B = Tuple{Type{T}, T} where T<:AbstractArray, I = typeintersect(A, B) @test !isconcretetype(I) @test I == Tuple{Type{T}, Vector{Any}} where T<:AbstractArray end @testintersect(Tuple{Type{Vector{<:T}}, T} where {T<:Integer}, Tuple{Type{T}, AbstractArray} where T<:Array, Bottom) struct S40{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, _Z7, _Z8, _Z9, _Z10, _Z11, _Z12, _Z13, _Z14} end @testintersect(Tuple{Type{S40{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, _Z7, _Z8, _Z9, _Z10, _Z11, _Z12, _Z13, _Z14}} where _Z14 where _Z13 where _Z12 where _Z11 where _Z10 where _Z9 where _Z8 where _Z7 where _Z6 where _Z5 where _Z4 where _Z3 where _Z2 where _Z1 where _Z where _Y where _X where _W where _V where _U where _T where _S where _R where _Q where _P where _O where _N where _M where _L where _K where _J where _I where _H where _G where _F where _E where _D where _C where _B where _A, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any}, Tuple{Type{S40{A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40} where A40 where A39 where A38 where A37 where A36 where A35 where A34 where A33 where A32 where A31 where A30 where A29 where A28 where A27 where A26 where A25 where A24 where A23 where A22 where A21 where A20 where A19 where A18 where A17 where A16 where A15 where A14 where A13 where A12 where A11 where A10 where A9 where A8 where A7 where A6 where A5 where A4 where A3 where A2 where A1}, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40} where A40 where A39 where A38 where A37 where A36 where A35 where A34 where A33 where A32 where A31 where A30 where A29 where A28 where A27 where A26 where A25 where A24 where A23 where A22 where A21 where A20 where A19 where A18 where A17 where A16 where A15 where A14 where A13 where A12 where A11 where A10 where A9 where A8 where A7 where A6 where A5 where A4 where A3 where A2 where A1, Bottom) let A = Tuple{Any, Type{Ref{_A}} where _A}, B = Tuple{Type{T}, Type{<:Union{Ref{T}, T}}} where T, I = typeintersect(A, B) @test I != Union{} @test Tuple{Type{Ref{Integer}}, Type{Ref{Integer}}} <: I @test !<:(Tuple{Type{Int}, Type{Int}}, I) end @testintersect(Tuple{Type{T}, T} where T<:(Tuple{Vararg{_A, _B}} where _B where _A), Tuple{Type{Tuple{Vararg{_A, N}} where _A<:F}, Pair{N, F}} where F where N, Bottom) # issue #42409 @testintersect(Tuple{Type{Pair{_A, S} where S<:AbstractMatrix{<:_A}}, Dict} where _A, Tuple{Type{Pair{_A, S} where S<:AbstractMatrix{<:_A}} where _A, Union{Array, Pair}}, Bottom) # https://github.com/JuliaLang/julia/issues/44735 @test_throws TypeError(:typeassert, Type, Vararg{Int}) typeintersect(Vararg{Int}, Int) @test_throws TypeError(:typeassert, Type, Vararg{Int}) typeintersect(Int, Vararg{Int}) @test_throws TypeError(:typeassert, Type, 1) typeintersect(1, Int) @test_throws TypeError(:typeassert, Type, 1) typeintersect(Int, 1) let A = Tuple{typeof(identity), Type{Union{}}}, B = Tuple{typeof(identity), typeof(Union{})} @test A == B && (Base.isdispatchtuple(A) == Base.isdispatchtuple(B)) end # issue #45703 # requires assertions enabled (to catch discrepancy in obvious_subtype) let T = TypeVar(:T, Real), V = TypeVar(:V, AbstractVector{T}), S = Type{Pair{T, V}} @test !(UnionAll(T, UnionAll(V, UnionAll(T, Type{Pair{T, V}}))) <: UnionAll(T, UnionAll(V, Type{Pair{T, V}}))) @test !(UnionAll(T, UnionAll(V, UnionAll(T, S))) <: UnionAll(T, UnionAll(V, S))) end # issue #41096 let C = Val{Val{B}} where {B} @testintersect(Val{<:Union{Missing, Val{false}, Val{true}}}, C, Val{<:Union{Val{true}, Val{false}}}) @testintersect(Val{<:Union{Nothing, Val{true}, Val{false}}}, C, Val{<:Union{Val{true}, Val{false}}}) @testintersect(Val{<:Union{Nothing, Val{false}}}, C, Val{Val{false}}) end #issue #43082 struct X43082{A, I, B<:Union{Ref{I},I}}; end @testintersect(Tuple{X43082{T}, Int} where T, Tuple{X43082{Int}, Any}, Tuple{X43082{Int}, Int}) #issue #36443 let C = Tuple{Val{3},Int,Int,Int}, As = (Tuple{Val{N},Vararg{T,N}} where {T,N}, Tuple{Val{N},Vararg{T,N}} where {N,T}), Bs = (Tuple{Val{3},Int,Vararg{T,N}} where {T,N}, Tuple{Val{3},Int,Vararg{T,N}} where {N,T}, Tuple{Val{3},Int,Vararg{T}} where {T}, Tuple{Val{3},Int,Vararg{T,2}} where {T}) for A in As, B in Bs @testintersect(A, B, C) end end let A = Tuple{Type{Val{N}},Tuple{Vararg{T,N}} where T} where N, C = Tuple{Type{Val{2}},Tuple{T,T} where T} @testintersect(A, Tuple{Type{Val{2}},Tuple{Vararg{T,N}} where T} where N, C) @testintersect(A, Tuple{Type{Val{2}},Tuple{T,Vararg{T,N}} where T} where N, C) @testintersect(A, Tuple{Type{Val{2}},Tuple{T,T,Vararg{T,N}} where T} where N, C) end let f36443(::NTuple{N}=[(f36443,),(1,2)][2],::Val{N}=Val(2)) where{N} = 0 @test f36443() == 0; end let C = Tuple{Val{3},Int,Int,Int,Int}, As = (Tuple{Val{N},Int,Vararg{T,N}} where {T,N}, Tuple{Val{N},Int,Vararg{T,N}} where {N,T}), Bs = (Tuple{Val{3},Vararg{T,N}} where {T,N}, Tuple{Val{3},Vararg{T,N}} where {N,T}, Tuple{Val{3},Vararg{T}} where {T}) for A in As, B in Bs @testintersect(A, B, C) end end #issue #37257 let T = Tuple{Val{N}, Any, Any, Vararg{Any,N}} where N, C = Tuple{Val{1}, Any, Any, Any} @testintersect(T, Tuple{Val{1}, Vararg{Any}}, C) @testintersect(T, Tuple{Val{1}, Any, Vararg{Any}}, C) @testintersect(T, Tuple{Val{1}, Any, Any, Vararg{Any}}, C) @testintersect(T, Tuple{Val{1}, Any, Any, Any, Vararg{Any}}, C) @testintersect(T, Tuple{Val{1}, Any, Any, Any, Any, Vararg{Any}}, Union{}) end let A = Tuple{NTuple{N,Any},Val{N}} where {N}, C = Tuple{NTuple{4,Any},Val{4}} @testintersect(A, Tuple{Tuple{Vararg{Any,N}},Val{4}} where {N}, C) @testintersect(A, Tuple{Tuple{Vararg{Any}},Val{4}}, C) @testintersect(A, Tuple{Tuple{Vararg{Any,N}} where {N},Val{4}}, C) @testintersect(A, Tuple{Tuple{Any,Vararg{Any,N}},Val{4}} where {N}, C) @testintersect(A, Tuple{Tuple{Any,Vararg{Any}},Val{4}}, C) @testintersect(A, Tuple{Tuple{Any,Vararg{Any,N}} where {N},Val{4}}, C) @testintersect(A, Tuple{Tuple{Any,Any,Any,Any,Any,Vararg{Any,N}},Val{4}} where {N}, Union{}) @testintersect(A, Tuple{Tuple{Any,Any,Any,Any,Any,Vararg{Any}},Val{4}}, Union{}) @testintersect(A, Tuple{Tuple{Any,Any,Any,Any,Any,Vararg{Any,N}} where {N},Val{4}}, Union{}) end #issue #39088 let a() = c((1,), (1,1,1,1)) c(d::NTuple{T}, ::NTuple{T}) where T = d c(d::NTuple{f}, b) where f = c((d..., f), b) j(h::NTuple{T}, ::NTuple{T} = a()) where T = nothing @test j((1,1,1,1)) === nothing end let A = Tuple{NTuple{N, Int}, NTuple{N, Int}} where N, C = Tuple{NTuple{4, Int}, NTuple{4, Int}} @testintersect(A, Tuple{Tuple{Int, Vararg{Any}}, NTuple{4, Int}}, C) @testintersect(A, Tuple{Tuple{Int, Vararg{Any, N}} where {N}, NTuple{4, Int}}, C) @testintersect(A, Tuple{Tuple{Int, Vararg{Any, N}}, NTuple{4, Int}} where {N}, C) Bs = (Tuple{Tuple{Int, Vararg{Any}}, Tuple{Int, Int, Vararg{Any}}}, Tuple{Tuple{Int, Vararg{Any,N1}}, Tuple{Int, Int, Vararg{Any,N2}}} where {N1,N2}, Tuple{Tuple{Int, Vararg{Any,N}} where {N}, Tuple{Int, Int, Vararg{Any,N}} where {N}}) C = Tuple{Tuple{Int, Int, Vararg{Int, N}}, Tuple{Int, Int, Vararg{Int, N}}} where {N} for B in Bs @testintersect(A, B, C) end A = Tuple{NTuple{N, Int}, Tuple{Int, Vararg{Int, N}}} where N C = Tuple{Tuple{Int, Vararg{Int, N}}, Tuple{Int, Int, Vararg{Int, N}}} where {N} for B in Bs @testintersect(A, B, C) end A = Tuple{Tuple{Int, Vararg{Int, N}}, NTuple{N, Int}} where N C = Tuple{Tuple{Int, Int, Int, Vararg{Int, N}}, Tuple{Int, Int, Vararg{Int, N}}} where {N} for B in Bs @testintersect(A, B, C) end end let A = Pair{NTuple{N, Int}, NTuple{N, Int}} where N, C = Pair{NTuple{4, Int}, NTuple{4, Int}} @testintersect(A, Pair{<:Tuple{Int, Vararg{Any}}, NTuple{4, Int}}, C) @testintersect(A, Pair{<:Tuple{Int, Vararg{Any, N}} where {N}, NTuple{4, Int}}, C) @testintersect(A, Pair{<:Tuple{Int, Vararg{Any, N}}, NTuple{4, Int}} where {N}, C) Bs = (Pair{<:Tuple{Int, Vararg{Int}}, <:Tuple{Int, Int, Vararg{Int}}}, Pair{Tuple{Int, Vararg{Int,N1}}, Tuple{Int, Int, Vararg{Int,N2}}} where {N1,N2}, Pair{<:Tuple{Int, Vararg{Int,N}} where {N}, <:Tuple{Int, Int, Vararg{Int,N}} where {N}}) C = Pair{Tuple{Int, Int, Vararg{Int, N}}, Tuple{Int, Int, Vararg{Int, N}}} where {N} for B in Bs @testintersect(A, B, C) end end # Example from pr#39098 @testintersect(NTuple, Tuple{Any,Vararg}, Tuple{T, Vararg{T}} where {T}) @testintersect(Val{T} where T<:Tuple{Tuple{Any, Vararg{Any}}}, Val{Tuple{Tuple{Vararg{Any, N}}}} where {N}, Val{Tuple{Tuple{Any, Vararg{Any, N}}}} where {N}) let A = Pair{NTuple{N, Int}, Val{N}} where N, C = Pair{Tuple{Int, Vararg{Int,N1}}, Val{N2}} where {N1,N2}, B = Pair{<:Tuple{Int, Vararg{Int}}, <:Val} @testintersect A B C @testintersect A C C end # issue #49484 let S = Tuple{Integer, U} where {II<:Array, U<:Tuple{Vararg{II, 1}}} T = Tuple{Int, U} where {II<:Array, U<:Tuple{Vararg{II, 1}}} @testintersect(S, Tuple{Int, U} where {U<:Tuple{Vararg{Any}}}, T) @testintersect(S, Tuple{Int, U} where {N, U<:Tuple{Vararg{Any,N}}}, T) @testintersect(S, Tuple{Int, U} where {U<:Tuple{Any,Vararg{Any}}}, T) @testintersect(S, Tuple{Int, U} where {N, U<:Tuple{Any,Vararg{Any,N}}}, T) @testintersect(S, Tuple{Int, U} where {U<:Tuple{Any,Any,Vararg{Any}}}, Union{}) @testintersect(S, Tuple{Int, U} where {N, U<:Tuple{Any,Any,Vararg{Any,N}}}, Union{}) end function equal_envs(env1, env2) length(env1) == length(env2) || return false for i = 1:length(env1) a = env1[i] b = env2[i] # Unwrap `svec(tvar, constrained)` markers for equality comparison. a isa Core.SimpleVector && (a = a[1]) b isa Core.SimpleVector && (b = b[1]) if a isa TypeVar if !(b isa TypeVar && a.name == b.name && a.lb == b.lb && a.ub == b.ub) return false end elseif !(a == b) return false end end return true end # issue #43064 let env_tuple(@nospecialize(x), @nospecialize(y)) = intersection_env(x, y)[2] TT0 = Tuple{Type{T},Union{Real,Missing,Nothing}} where {T} TT1 = Union{Type{Int8},Type{Int16}} e1 = env_tuple(Tuple{TT1,Missing}, TT0) e2 = env_tuple(Tuple{TT1,Nothing}, TT0) e3 = env_tuple(Tuple{TT1,Int}, TT0) @test equal_envs(e1, e2) && equal_envs(e2, e3) && equal_envs(e3, Core.svec(TT0.var)) TT0 = Tuple{T1,T2,Union{Real,Missing,Nothing}} where {T1,T2} TT1 = Tuple{T1,T2,Union{Real,Missing,Nothing}} where {T2,T1} TT2 = Tuple{Union{Int,Int8},Union{Int,Int8},Int} TT3 = Tuple{Int,Union{Int,Int8},Int} @test equal_envs(env_tuple(TT2, TT0), Core.svec(TypeVar(:T1, Union{Int, Int8}), TypeVar(:T2, Union{Int, Int8}))) @test equal_envs(env_tuple(TT2, TT1), Core.svec(TypeVar(:T2, Union{Int, Int8}), TypeVar(:T1, Union{Int, Int8}))) @test equal_envs(env_tuple(TT3, TT0), Core.svec(Int, TypeVar(:T2, Union{Int, Int8}))) @test equal_envs(env_tuple(TT3, TT1), Core.svec(TypeVar(:T2, Union{Int, Int8}), Int)) TT0 = Tuple{T1,T2,T1,Union{Real,Missing,Nothing}} where {T1,T2} TT1 = Tuple{T1,T2,T1,Union{Real,Missing,Nothing}} where {T2,T1} TT2 = Tuple{Int,Union{Int,Int8},Int,Int} @test equal_envs(env_tuple(TT2, TT0), Core.svec(Int, TypeVar(:T2, Union{Int, Int8}))) @test equal_envs(env_tuple(TT2, TT1), Core.svec(TypeVar(:T2, Union{Int, Int8}), Int)) end #issue #46735 T46735{B<:Real} = Pair{<:Union{B, Val{<:B}}, <:Union{AbstractMatrix{B}, AbstractMatrix{Vector{B}}}} @testintersect(T46735{B} where {B}, T46735, !Union{}) @testintersect(T46735{B} where {B<:Integer}, T46735, !Union{}) S46735{B<:Val, M<:AbstractMatrix} = Tuple{<:Union{B, <:Val{<:B}},M,<:(Union{AbstractMatrix{B}, AbstractMatrix{<:Vector{<:B}}})} @testintersect(S46735{B} where {B}, S46735, !Union{}) @testintersect(S46735{B, M} where {B, M}, S46735, !Union{}) A46735{B<:Val, M<:AbstractMatrix} = Tuple{<:Union{B, <:Val{<:B}},M,Union{AbstractMatrix{B}, AbstractMatrix{<:Vector{<:B}}}} @testintersect(A46735{B} where {B}, A46735, !Union{}) @testintersect(A46735{B, M} where {B, M}, A46735, !Union{}) #issue #46871 #38497 struct A46871{T, N, M} <: AbstractArray{T, N} end struct B46871{T, N} <: Ref{A46871{T, N, N}} end for T in (B46871{Int, N} where {N}, B46871{Int}) # intentional duplication @testintersect(T, Ref{<:AbstractArray{<:Real, 3}}, B46871{Int, 3}) end abstract type C38497{e,g<:Tuple,i} end struct Q38497{o,e<:NTuple{o},g} <: C38497{e,g,Array{o}} end @testintersect(Q38497{<:Any, Tuple{Int}}, C38497, Q38497{<:Any, Tuple{Int}, <:Tuple}) # n.b. the only concrete instance of this type is Q38497{1, Tuple{Int}, <:Tuple} (since NTuple{o} also adds an ::Int constraint) # but this abstract type is also part of the intersection abstractly abstract type X38497{T<:Number} end abstract type Y38497{T>:Integer} <: X38497{T} end struct Z38497{T>:Int} <: Y38497{T} end @testintersect(Z38497, X38497, Z38497{T} where Int<:T<:Number) @testintersect(Z38497, Y38497, Z38497{T} where T>:Integer) @testintersect(X38497, Y38497, Y38497{T} where Integer<:T<:Number) #issue #33138 @test Vector{Vector{Tuple{T,T}} where Int<:T<:Int} <: Vector{Vector{Tuple{S1,S1} where S<:S1<:S}} where S #issue #46970 let e = only(intersection_env(Union{S, Matrix{Int}} where S<:Matrix, Matrix)[2]) @test e isa Core.SimpleVector && e[1] isa TypeVar end T46784{B<:Val, M<:AbstractMatrix} = Tuple{<:Union{B, <:Val{<:B}}, M, Union{AbstractMatrix{B}, AbstractMatrix{<:Vector{<:B}}}} @testintersect(T46784{T,S} where {T,S}, T46784, !Union{}) @test T46784 <: T46784{T,S} where {T,S} #issue 36185 let S = Tuple{Type{T},Array{Union{T,Missing},N}} where {T,N}, T = Tuple{Type{T},Array{Union{T,Nothing},N}} where {T,N} I = typeintersect(S, T) @test I == typeintersect(T, S) != Union{} @test_broken I <: S @test_broken I <: T end #issue 46736 let S = Tuple{Val{T}, T} where {S1,T<:Val{Union{Nothing,S1}}}, T = Tuple{Val{Val{Union{Nothing, S2}}}, Any} where S2 @testintersect(S, T, Tuple{Val{Val{Union{Nothing, S1}}}, Val{Union{Nothing, S1}}} where S1) end #issue #47874:case1 let S1 = Tuple{Int, Any, Union{Val{C1}, C1}} where {R1<:Real, C1<:Union{Complex{R1}, R1}}, S2 = Tuple{Int, Any, Union{Val{C1}, C1} where {R1<:Real, C1<:Union{Complex{R1}, R1}}}, T1 = Tuple{Any, Int, Union{Val{C2}, C2}} where {R2<:Real, C2<:Union{Complex{R2}, R2}}, T2 = Tuple{Any, Int, V} where {R2<:Real, C2<:Union{Complex{R2}, R2}, V<:Union{Val{C2}, C2}} for S in (S1, S2), T in (T1, T2) @testintersect(S, T, !Union{}) end end #issue #47874:case2 let S = Tuple{Int, Vararg{Val{C} where C<:Union{Complex{R}, R}}} where R T = Tuple{Any, Vararg{Val{C} where C<:Union{Complex{R}, R}}} where R<:Real I = Tuple{Any, Vararg{Val{C} where C<:Union{Complex{R}, R}}} where R<:Real @testintersect(S, T, !Union{}) @test_broken typeintersect(S, T) == I @test_broken typeintersect(T, S) == I end #issue #47874:case3 let S = Tuple{Int, Tuple{Vararg{Val{C1} where C1<:Union{Complex{R1}, R1}}} where R1<:(Union{Real, V1} where V1), Tuple{Vararg{Val{C2} where C2<:Union{Complex{R2}, Complex{R3}, R3}}} where {R2<:(Union{Real, V2} where V2), R3<:Union{Complex{R2}, Real, R2}}}, T = Tuple{Any, Tuple{Vararg{Val{CC1} where CC1<:Union{Complex{R}, R}}}, Tuple{Vararg{Val{CC2} where CC2<:Union{Complex{R}, R}}}} where R<:Real @testintersect(S, T, !Union{}) end let S = Tuple{T2, V2} where {T2, N2, V2<:(Array{S2, N2} where {S2 <: T2})}, T = Tuple{V1, T1} where {T1, N1, V1<:(Array{S1, N1} where {S1 <: T1})} @testintersect(S, T, !Union{}) end let S = Dict{Int, S1} where {F1, S1<:Union{Int8, Val{F1}}}, T = Dict{F2, S2} where {F2, S2<:Union{Int8, Val{F2}}} @test_broken typeintersect(S, T) == Dict{Int, S} where S<:Union{Val{Int}, Int8} @test typeintersect(T, S) == Dict{Int, S} where S<:Union{Val{Int}, Int8} end # Ensure inner `intersect_all` never under-estimate. let S = Tuple{F1, Dict{Int, S1}} where {F1, S1<:Union{Int8, Val{F1}}}, T = Tuple{Any, Dict{F2, S2}} where {F2, S2<:Union{Int8, Val{F2}}} @test Tuple{Nothing, Dict{Int, Int8}} <: S @test Tuple{Nothing, Dict{Int, Int8}} <: T @test Tuple{Nothing, Dict{Int, Int8}} <: typeintersect(S, T) @test Tuple{Nothing, Dict{Int, Int8}} <: typeintersect(T, S) end let S = Tuple{F1, Val{S1}} where {F1, S1<:Dict{F1}} T = Tuple{Any, Val{S2}} where {F2, S2<:Union{map(T->Dict{T}, Base.BitInteger_types)...}} ST = typeintersect(S, T) TS = typeintersect(S, T) for U in Base.BitInteger_types @test Tuple{U, Val{Dict{U,Nothing}}} <: S @test Tuple{U, Val{Dict{U,Nothing}}} <: T @test Tuple{U, Val{Dict{U,Nothing}}} <: ST @test Tuple{U, Val{Dict{U,Nothing}}} <: TS end end #issue 55206 struct T55206{A,B<:Complex{A},C<:Union{Dict{Nothing},Dict{A}}} end @testintersect(T55206, T55206{<:Any,<:Any,<:Dict{Nothing}}, T55206{A,<:Complex{A},<:Dict{Nothing}} where {A}) @testintersect( Tuple{Dict{Int8, Int16}, Val{S1}} where {F1, S1<:AbstractSet{F1}}, Tuple{Dict{T1, T2}, Val{S2}} where {T1, T2, S2<:Union{Set{T1},Set{T2}}}, Tuple{Dict{Int8, Int16}, Val{S1}} where {S1<:Union{Set{Int8},Set{Int16}}} ) f48167(::Type{Val{L2}}, ::Type{Union{Val{L1}, Set{R}}}) where {L1, R, L2<:L1} = 1 f48167(::Type{Val{L1}}, ::Type{Union{Val{L2}, Set{R}}}) where {L1, R, L2<:L1} = 2 f48167(::Type{Val{L}}, ::Type{Union{Val{L}, Set{R}}}) where {L, R} = 3 @test f48167(Val{Nothing}, Union{Val{Nothing}, Set{Int}}) == 3 # https://github.com/JuliaLang/julia/pull/31167#issuecomment-1358381818 let S = Tuple{Type{T1}, T1, Val{T1}} where T1<:(Val{S1} where S1<:Val), T = Tuple{Union{Type{T2}, Type{S2}}, Union{Val{T2}, Val{S2}}, Union{Val{T2}, S2}} where T2<:Val{A2} where A2 where S2<:Val I1 = typeintersect(S, T) I2 = typeintersect(T, S) @test I1 !== Union{} && I2 !== Union{} @test_broken I1 <: S @test_broken I2 <: T @test_broken I2 <: S @test_broken I2 <: T end #issue 44395 @testintersect(Tuple{Type{T}, T} where {T <: Vector{Union{T, R}} where {R<:Real, T<:Real}}, Tuple{Type{Vector{Union{T, R}}}, Matrix{Union{T, R}}} where {R<:Real, T<:Real}, Union{}) #issue 26487 @testintersect(Tuple{Type{Tuple{T,Val{T}}}, Val{T}} where T, Tuple{Type{Tuple{Val{T},T}}, Val{T}} where T, Union{}) @test only(intersection_env(Val{Union{Val{Val{T}} where {T},Int}}, Val{Union{T,Int}} where T)[2]) === Val{Val{T}} where {T} # issue 47654 Vec47654{T} = Union{AbstractVector{T}, AbstractVector{Union{T,Nothing}}} struct Wrapper47654{T, V<:Vec47654{T}} v::V end abstract type P47654{A} end @test Wrapper47654{P47654, Vector{Union{P47654,Nothing}}} <: Wrapper47654 #issue 41561 @testintersect(Tuple{Vector{VT}, Vector{VT}} where {N1, VT<:AbstractVector{N1}}, Tuple{Vector{VN} where {N, VN<:AbstractVector{N}}, Vector{Vector{Float64}}}, Tuple{Vector{Vector{Float64}}, Vector{Vector{Float64}}}) @testset "known subtype/intersect issue" begin #issue 45874 let S = Pair{Val{P}, AbstractVector{<:Union{P,<:AbstractMatrix{P}}}} where P, T = Pair{Val{R}, AbstractVector{<:Union{P,<:AbstractMatrix{P}}}} where {P,R} @test S <: T end #issue 40865 @test Tuple{Set{Ref{Int}}, Set{Ref{Int}}} <: Tuple{Set{KV}, Set{K}} where {K,KV<:Union{K,Ref{K}}} @test Tuple{Set{Val{Int}}, Set{Val{Int}}} <: Tuple{Set{KV}, Set{K}} where {K,KV<:Union{K,Val{K}}} #issue 39099 A = Tuple{Tuple{Int, Int, Vararg{Int, N}}, Tuple{Int, Vararg{Int, N}}, Tuple{Vararg{Int, N}}} where N B = Tuple{NTuple{N, Int}, NTuple{N, Int}, NTuple{N, Int}} where N @test_broken !(A <: B) #issue 35698 @test typeintersect(Type{Tuple{Vector{T} where T}}, UnionAll) != Union{} #issue 33137 @test (Tuple{Q,Int} where Q<:Int) <: Tuple{T,T} where T # issue 24333 @test (Type{Union{Ref,Cvoid}} <: Type{Union{T,Cvoid}} where T) # issue 22123 t1 = Ref{Ref{Ref{Union{Int64, T}}} where T} t2 = Ref{Ref{Ref{Union{T, S}}} where T} where S @test t1 <: t2 # issue 21153 @test_broken (Tuple{T1,T1} where T1<:(Val{T2} where T2)) <: (Tuple{Val{S},Val{S}} where S) end # issue #47658 let T = Ref{NTuple{8, Ref{Union{Int, P}}}} where P, S = Ref{NTuple{8, Ref{Union{Int, P}}}} where P # note T and S are identical but we need 2 copies to avoid being fooled by pointer equality @test T <: Union{Int, S} end # issue #61602 struct W61602{T, N} x::Array{T, N} end let A = W61602{T, 1} where T<:(Union{Missing, S} where S), B = W61602{Union{Missing, T}} where T C = W61602{Union{Missing, Int64}, 1} @test C <: typeintersect(A, B) @test C <: typeintersect(B, A) D = Tuple{W61602{T, 1}, X} where {T<:(Union{Missing, S} where S), X} E = Tuple{W61602{Union{Missing, T}}, T} where T @test Tuple{C, String} <: D @test !(Tuple{C, String} <: E) @test Tuple{C, Int64} <: typeintersect(D, E) @test Tuple{C, Int64} <: typeintersect(E, D) @test_broken !(Tuple{C, String} <: typeintersect(D, E)) @test_broken !(Tuple{C, String} <: typeintersect(E, D)) end # try to fool a greedy algorithm that picks X=Int, Y=String here @test Tuple{Ref{Union{Int,String}}, Ref{Union{Int,String}}} <: Tuple{Ref{Union{X,Y}}, Ref{X}} where {X,Y} @test Tuple{Ref{Union{Int,String,Missing}}, Ref{Union{Int,String}}} <: Tuple{Ref{Union{X,Y}}, Ref{X}} where {X,Y} @test !(Tuple{Any, Any, Any} <: Tuple{Any, Vararg{T}} where T) # issue #39967 @test (NTuple{27, T} where {S, T<:Union{Array, Array{S}}}) <: Tuple{Array, Array, Vararg{AbstractArray, 25}} abstract type MyAbstract47877{C}; end struct MyType47877{A,B} <: MyAbstract47877{A} end let A = Tuple{Type{T}, T} where T, B = Tuple{Type{MyType47877{W, V} where V<:Union{Base.BitInteger, MyAbstract47877{W}}}, MyAbstract47877{<:Base.BitInteger}} where W C = Tuple{Type{MyType47877{W, V} where V<:Union{MyAbstract47877{W}, Base.BitInteger}}, MyType47877{W, V} where V<:Union{MyAbstract47877{W}, Base.BitInteger}} where W<:Base.BitInteger # ensure that merge_env for innervars does not blow up (the large Unions ensure this will take excessive memory if it does) @testintersect(A, B, C) end let a = (isodd(i) ? Pair{Char, String} : Pair{String, String} for i in 1:2000) @test Tuple{Type{Pair{Union{Char, String}, String}}, a...} <: Tuple{Type{Pair{K, V}}, Vararg{Pair{A, B} where B where A}} where V where K a = (isodd(i) ? Matrix{Int} : Vector{Int} for i in 1:4000) @test Tuple{Type{Pair{Union{Char, String}, String}}, a...,} <: Tuple{Type{Pair{K, V}}, Vararg{Array}} where V where K end #issue 48582 @test !<:(Tuple{Pair{<:T,<:T}, Val{S} where {S}} where {T<:Base.BitInteger}, Tuple{Pair{<:T,<:T}, Val{Int}} where {T<:Base.BitInteger}) struct T48695{T, N, H<:AbstractArray} <: AbstractArray{Union{Missing, T}, N} end struct S48695{T, N, H<:AbstractArray{T, N}} <: AbstractArray{T, N} end let S = Tuple{Type{S48695{T, 2, T48695{B, 2, C}}} where {T<:(Union{Missing, A} where A), B, C}, T48695{T, 2} where T}, T = Tuple{Type{S48695{T, N, H}}, H} where {T, N, H<:AbstractArray{T, N}} V = typeintersect(S, T) vars_in_unionall(s) = s isa UnionAll ? (s.var, vars_in_unionall(s.body)...) : () @test V != Union{} @test allunique(vars_in_unionall(V)) @test typeintersect(V, T) != Union{} end #issue 48961 @test !<:(Type{Union{Missing, Int}}, Type{Union{Missing, Nothing, Int}}) #issue 49127 struct F49127{m,n} <: Function end let a = [TypeVar(:V, Union{}, Function) for i in 1:32] b = a[1:end-1] S = foldr((v, d) -> UnionAll(v, d), a; init = foldl((i, j) -> F49127{i, j}, a)) T = foldr((v, d) -> UnionAll(v, d), b; init = foldl((i, j) -> F49127{i, j}, b)) @test S <: T end # requires assertions enabled (to test union-split in `obviously_disjoint`) @test !<:(Tuple{Type{Int}, Int}, Tuple{Type{Union{Int, T}}, T} where T<:Union{Int8,Int16}) @test <:(Tuple{Type{Int}, Int}, Tuple{Type{Union{Int, T}}, T} where T<:Union{Int8,Int}) #issue #49354 (requires assertions enabled) @test !<:(Tuple{Type{Union{Int, Val{1}}}, Int}, Tuple{Type{Union{Int, T1}}, T1} where T1<:Val) @test !<:(Tuple{Type{Union{Int, Val{1}}}, Int}, Tuple{Type{Union{Int, T1}}, T1} where T1<:Union{Val,Pair}) @test <:(Tuple{Type{Union{Int, Val{1}}}, Int}, Tuple{Type{Union{Int, T1}}, T1} where T1<:Union{Integer,Val}) @test <:(Tuple{Type{Union{Int, Int8}}, Int}, Tuple{Type{Union{Int, T1}}, T1} where T1<:Integer) @test !<:(Tuple{Type{Union{Pair{Int, Any}, Pair{Int, Int}}}, Pair{Int, Any}}, Tuple{Type{Union{Pair{Int, Any}, T1}}, T1} where T1<:(Pair{T,T} where {T})) let A = Tuple{Type{T}, T, Val{T}} where T, B = Tuple{Type{S}, Val{S}, Val{S}} where S @test_broken typeintersect(A, B) == Tuple{Type{T}, Val{T}, Val{T}} where T>:Val @test typeintersect(A, B) <: Tuple{Type{T}, Val{T}, Val{T}} where T end let A = Tuple{Type{T}, T, Val{T}} where T<:Val, B = Tuple{Type{S}, Val{S}, Val{S}} where S<:Val @test_broken typeintersect(A, B) == Tuple{Type{Val}, Val{Val}, Val{Val}} @test typeintersect(A, B) <: Tuple{Type{T}, Val{T}, Val{T}} where T<:Val end let A = Tuple{Type{T}, T, Val{T}} where T<:Val, B = Tuple{Type{S}, Val{S}, Val{S}} where S<:Val{A} where A @test typeintersect(A, B) == Union{} end let A = Tuple{Type{T}, T, Val{T}} where T<:Val{<:Val}, B = Tuple{Type{S}, Val{S}, Val{S}} where S<:Val @test_broken typeintersect(A, B) == Tuple{Type{Val{<:Val}}, Val{Val{<:Val}}, Val{Val{<:Val}}} @test typeintersect(A, B) <: Tuple{Type{T}, Val{T}, Val{T}} where T<:(Val{<:Val}) end let T = Tuple{Union{Type{T}, Type{S}}, Union{Val{T}, Val{S}}, Union{Val{T}, S}} where T<:Val{A} where A where S<:Val, S = Tuple{Type{T}, T, Val{T}} where T<:(Val{S} where S<:Val) # optimal = Union{}? @test typeintersect(T, S) == Tuple{Type{T}, Union{Val{T}, Val{S}}, Val{T}} where {S<:Val, T<:Val} @test typeintersect(S, T) == Tuple{Type{T}, Union{Val{T}, Val{S}}, Val{T}} where {T<:Val, S<:(Union{Val{A}, Val} where A)} end #issue #49857 @test !<:(Type{Vector{Union{Base.BitInteger, Base.IEEEFloat, StridedArray, Missing, Nothing, Val{T}}}} where {T}, Type{Array{T}} where {T}) #issue 50195 let a = Tuple{Type{X} where X<:Union{Nothing, Val{X1} where {X4, X1<:(Pair{X2, Val{X2}} where X2<:Val{X4})}}}, b = Tuple{Type{Y} where Y<:(Val{Y1} where {Y4<:Src, Y1<:(Pair{Y2, Val{Y2}} where Y2<:Union{Val{Y4}, Y4})})} where Src @test typeintersect(a, b) <: Any end #issue 50195 let a = Tuple{Union{Nothing, Type{Pair{T1}} where T1}} b = Tuple{Type{X2} where X2<:(Pair{T2, Y2} where {Src, Z2<:Src, Y2<:Union{Val{Z2}, Z2}})} where T2 @test !Base.has_free_typevars(typeintersect(a, b)) end #issue 53366 let Y = Tuple{Val{T}, Val{Val{T}}} where T A = Val{Val{T}} where T T = TypeVar(:T, UnionAll(A.var, Val{A.var})) B = UnionAll(T, Val{T}) X = Tuple{A, B} @testintersect(X, Y, !Union{}) end #issue 53621 (requires assertions enabled) abstract type A53621{T, R, C, U} <: AbstractSet{Union{C, U}} end struct T53621{T, R<:Real, C, U} <: A53621{T, R, C, U} end let U = TypeVar(:U) C = TypeVar(:C) T = TypeVar(:T) R = TypeVar(:R) CC = TypeVar(:CC, Union{C, U}) UU = TypeVar(:UU, Union{C, U}) S1 = UnionAll(T, UnionAll(R, Type{UnionAll(C, UnionAll(U, T53621{T, R, C, U}))})) S2 = UnionAll(C, UnionAll(U, UnionAll(CC, UnionAll(UU, UnionAll(T, UnionAll(R, T53621{T, R, CC, UU})))))) S = Tuple{S1, S2} T = Tuple{Type{T53621{T, R}}, AbstractSet{T}} where {T, R} @testintersect(S, T, !Union{}) end #issue 53371 struct T53371{A,B,C,D,E} end S53371{A} = Union{Int, <:A} R53371{A} = Val{V} where V<:(T53371{B,C,D,E,F} where {B<:Val{A}, C<:S53371{B}, D<:S53371{B}, E<:S53371{B}, F<:S53371{B}}) let S = Type{T53371{A, B, C, D, E}} where {A, B<:R53371{A}, C<:R53371{A}, D<:R53371{A}, E<:R53371{A}}, T = Type{T53371{A, B, C, D, E} where {A, B<:R53371{A}, C<:R53371{A}, D<:R53371{A}, E<:R53371{A}}} @test !(S <: T) end #issue 54356 let S = Tuple{Val{Val{Union{Val{A2}, A2}}}, Val{Val{Union{Val{A2}, Val{A4}, A4}}}} where {A2, A4<:Union{Val{A2}, A2}}, T = Tuple{Vararg{Val{V}}} where {V} @testintersect(S, T, !Union{}) end #issue 54356 abstract type A54356{T<:Real} end struct B54356{T} <: A54356{T} end struct C54356{S,T<:Union{S,Complex{S}}} end struct D54356{S<:Real,T} end let S = Tuple{Val, Val{T}} where {T}, R = Tuple{Val{Val{T}}, Val{T}} where {T}, SS = Tuple{Val, Val{T}, Val{T}} where {T}, RR = Tuple{Val{Val{T}}, Val{T}, Val{T}} where {T} # parameters check for self @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, Complex{B}}}, S{1}, R{1}) # parameters check for supertype (B54356 -> A54356) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, B54356{B}}}, S{1}, R{1}) # ensure unused TypeVar skips the `UnionAll` wrapping @testintersect(Tuple{Val{A}, A} where {B, A<:(Union{Val{B}, D54356{B,C}} where {C})}, S{1}, R{1}) # invariant parameter should not get narrowed @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, Val{Union{Int,Complex{B}}}}}, S{1}, R{1}) # bit value could not be `Union` element @testintersect(Tuple{Val{A}, A, Val{B}} where {B, A<:Union{B, Val{B}}}, SS{1}, RR{1}) @testintersect(Tuple{Val{A}, A, Val{B}} where {B, A<:Union{B, Complex{B}}}, SS{1}, Union{}) # `check_datatype_parameters` should ignore bad `Union` elements in constraint's ub T = Tuple{Val{Union{Val{Nothing}, Val{C54356{V,V}}}}, Val{Nothing}} where {Nothing<:V<:Nothing} @test T <: S{Nothing} @test T <: Tuple{Val{A}, A} where {B, C, A<:Union{Val{B}, Val{C54356{B,C}}}} @test T <: typeintersect(Tuple{Val{A}, A} where {B, C, A<:Union{Val{B}, Val{C54356{B,C}}}}, S{Nothing}) # extra check for Vararg @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NTuple{B,Any}}}, S{-1}, R{-1}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, Tuple{Any,Vararg{Any,B}}}}, S{-1}, R{-1}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, Tuple{Vararg{Int,Union{Int,Complex{B}}}}}}, S{1}, R{1}) # extra check for NamedTuple @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NamedTuple{B,Tuple{Int}}}}, S{1}, R{1}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NamedTuple{B,Tuple{Int}}}}, S{(1,)}, R{(1,)}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NamedTuple{(:a),B}}}, S{NTuple{2,Int}}, R{NTuple{2,Int}}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NamedTuple{B,Tuple{Int,Int}}}}, S{(:a,:a)}, R{(:a,:a)}) # extra check for GenericMemory/GenericMemoryRef @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, GenericMemory{B}}}, S{1}, R{1}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, GenericMemory{:not_atomic,Int,B}}}, S{1}, R{1}) end #issue 54516 let S = Tuple{Val{<:T}, Union{Int,T}} where {T}, T = Tuple{Union{Int,T}, Val{<:T}} where {T} @testintersect(S, T, !Union{}) @test !Base.has_free_typevars(typeintersect(S, T)) end #issue 55230 let T1 = NTuple{12, Union{Val{1}, Val{2}, Val{3}, Val{4}, Val{5}, Val{6}}} T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any} @test T1 <: T2 T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Val} @test T1 <: T2 T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Real} @test !(T1 <: T2) T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Union{Val,Real}} @test T1 <: T2 T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Union{String,Real}} @test !(T1 <: T2) T2 = Tuple{<:Union{Val,Real},<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any} @test T1 <: T2 T2 = Tuple{<:Union{String,Real},<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any} @test !(T1 <: T2) @test Tuple{Union{Val{1},Val{2}}} <: Tuple{S} where {T, S<:Val{T}} end #issue 56040 let S = Dict{V,V} where {V}, T = Dict{Ref{Union{Set{A2}, Set{A3}, A3}}, Ref{Union{Set{A3}, Set{A2}, Set{A1}, Set{A4}, A4}}} where {A1, A2<:Set{A1}, A3<:Union{Set{A1}, Set{A2}}, A4<:Union{Set{A2}, Set{A1}, Set{A3}}}, A = Dict{Ref{Set{Union{}}}, Ref{Set{Union{}}}} @testintersect(S, T, !Union{}) @test A <: typeintersect(S, T) @test A <: typeintersect(T, S) end #issue 56606 let A = Tuple{Val{1}} B = Tuple{Val} for _ in 1:30 A = Tuple{Val{A}} B = Tuple{Val{<:B}} end @test A <: B end @testintersect( Val{Tuple{Int,S,T}} where {S<:Any,T<:Vector{Vector{Int}}}, Val{Tuple{T,R,S}} where {T,R<:Vector{T},S<:Vector{R}}, Val{Tuple{Int, Vector{Int}, T}} where T<:Vector{Vector{Int}}, ) #issue 57429 @testintersect( Pair{<:Any, <:Tuple{Int}}, Pair{N, S} where {N, NTuple{N,Int}<:S<:NTuple{M,Int} where {M}}, !Union{} ) @testintersect( Pair{N, T} where {N,NTuple{N,Int}<:T<:NTuple{N,Int}}, Pair{N, T} where {N,NTuple{N,Int}<:T<:Tuple{Int,Vararg{Int}}}, !Union{} ) #issue 57852 @testintersect( Tuple{Type{T}, Type{<:F}, Type{<:F}} where {T, F<:Union{String, T}}, Tuple{Type{Complex{T}} where T, Type{Complex{T}} where T, Type{String}}, Tuple{Type{Complex{T}}, Type{Complex{T}}, Type{String}} where T ) @testintersect( Tuple{Type{T}, Type{<:Union{F, Nothing}}, Type{<:Union{F, Nothing}}} where {T, F<:Union{String, T}}, Tuple{Type{Complex{T}} where T, Type{Complex{T}} where T, Type{String}}, Tuple{Type{Complex{T}}, Type{Complex{T}}, Type{String}} where T ) #issue 58129 for k in 1:500 @eval struct $(Symbol(:T58129, k)){T} end end let Tvar = TypeVar(:Tvar) V = UnionAll(Tvar, Union{(@eval($(Symbol(:T58129, k)){$Tvar}) for k in 1:500)...}) @test Set{<:V} <: AbstractSet{<:V} end let Tvar1 = TypeVar(:Tvar1), Tvar2 = TypeVar(:Tvar2) V1 = UnionAll(Tvar1, Union{(@eval($(Symbol(:T58129, k)){$Tvar1}) for k in 1:100)...}) V2 = UnionAll(Tvar2, Union{(@eval($(Symbol(:T58129, k)){$Tvar2}) for k in 1:100)...}) @test Set{<:V2} <: AbstractSet{<:V1} end #issue 58115 @test Tuple{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{ Union{Tuple{}, Tuple{Tuple{}}}}}}}}}}}}} , Tuple{}} <: Tuple{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{Tuple{Vararg{Union{Tuple{}, Tuple{Tuple{}}}}}}}}}}}}}}}, Tuple{}} # issue 59490 @test typeintersect(Tuple{DataType, Type{UnitRange{Int64}}, Type{Int64}}, Tuple{Type{T}, S, S} where {T<:AbstractArray, S<:Type{<:Any}}) !== Union{} @test typeintersect(Tuple{DataType, Type{UnitRange{Int64}}, Type{Int64}}, Tuple{Type{T}, Vararg{S, N}} where {N, eT, T<:AbstractArray{eT, N}, S<:Type{<:Any}}) !== Union{} @test typeintersect(Tuple{Union{DataType, UnionAll, Union}, Type{UnitRange{Int64}}, Type{Int64}}, Tuple{Type{T}, Vararg{S, N}} where {N, eT, T<:AbstractArray{eT, N}, S<:Type{<:Any}}) !== Union{} @test typeintersect(Tuple{Int64, String}, Tuple{T, T} where T) === Union{} @test typeintersect(Tuple{Any, Union{Type{Vector},Type{Int64}}, Type{Int8}}, Tuple{Int64, S, S} where {S}) === Tuple{Int64, Type{Int64}, Type{Int8}} @test typeintersect(Tuple{Ref{DataType}, Type{Int64}, Type{Float64}, Union{Int64,String}}, (Tuple{Ref{T}, S, S, Int64} where {S<:T}) where T) === Tuple{Ref{DataType}, Type{Int64}, Type{Float64}, Int64} @test typeintersect(Tuple{Type{Int64}, Type{String}}, Tuple{S, S} where S<:Type{<:Number}) === Union{} @test typeintersect(Tuple{Type{Vector{T}} where T, Type{Int64}}, Tuple{S, S} where S) === Tuple{Type{Vector{T}} where T, Type{Int64}} # not a subtype under #33136 (mixed-tag member pairs), but the intersection # keeps the tag-homogeneous slices @test !(Tuple{Union{Type{Vector{T}} where T, Type{Int64}}, Type{Int8}} <: Tuple{S, S} where S) @test typeintersect(Tuple{Union{Type{Int64}, Ref{Int64}}, Ref{Int64}}, Tuple{S, S} where S) === Tuple{S, S} where S<:Ref{Int64} # the diagonal `T` can be `UnionAll` (both slots have `UnionAll`-tagged members # under `==`-class semantics), so the `Type{Int64}` component contributes too and # the result widens accordingly @test typeintersect(Tuple{Union{Type{Val},Type{Int64}}, Type{Vector}}, Tuple{T, T} where T<:Union{UnionAll,Type{<:Number}}) === Tuple{UnionAll, Type{Vector}} @test typeintersect(Tuple{Union{Type{Val}, Type{Int8}}, Union{Type{Val}, Type{Int64}}}, NTuple{2,<:Union{Type{<:Val}, DataType}}) == (Tuple{S, S} where S <: Union{Type{Val}, DataType}) @test typeintersect(Tuple{Union{Type{Val}, Type{Int64}}, DataType}, Tuple{S, S} where S) === Tuple{Type{Int64}, DataType} let A = Tuple{Union{Type{Vector}, Type{Int64}}, Union{Type{Matrix}, Type{Float64}}} B = (Tuple{S, S} where S) r = typeintersect(A, B) @test Tuple{Type{Vector}, Type{Matrix}} <: r # `Type{Int64}` and `Type{Float64}` have mixed-tag member pairs (#33136), # so that pair no longer lies in a diagonal `S`; the tag-pinned dispatch # key for the corresponding call still does @test !(Tuple{Type{Int64}, Type{Float64}} <: r) @test Tuple{Core.TypeEgal{Int64}, Core.TypeEgal{Float64}} <: r @test r <: B A = Tuple{Union{Type{Vector}, Type{Int64}}, Union{Type{Int64}, Type{Float64}}, Union{Type{Matrix}, Type{Float64}}} B = (Tuple{S, S, T} where S) where T r = typeintersect(A, B) # under #33136 the diagonal cannot be preserved in an expressible result # that also stays inside `B`; the result keeps the argument bound instead @test r <: A @test r !== Union{} end # JETLS#509 — inference hang with Union-bounded parametric types # subtype_ccheck leaked right-side Union choices into the shared # Runions statestack, causing exponential state iteration when # multiple Union-bounded parameters share a common variable. struct JETLS509S{F, A<:Union{Ref{F},Val{F}}, B<:Union{Ref{F},Val{F}}, C<:Union{Ref{F},Val{F}}, D<:Union{Ref{F},Val{F}}, E<:Union{Ref{F},Val{F}}, G<:Union{Ref{F},Val{F}}} end JETLS509f(a::JETLS509S{F}, b::JETLS509S{F}, s::Union{Nothing,Ref{F}}=nothing) where {F} = 1 let tt = Tuple{typeof(JETLS509f), JETLS509S{F,A,B,C,D,E,G} where { A<:Union{Ref{F},Val{F}}, B<:Union{Ref{F},Val{F}}, C<:Union{Ref{F},Val{F}}, D<:Union{Ref{F},Val{F}}, E<:Union{Ref{F},Val{F}}, G<:Union{Ref{F},Val{F}}}, JETLS509S{F,A,B,C,D,E,G} where { A<:Union{Ref{F},Val{F}}, B<:Union{Ref{F},Val{F}}, C<:Union{Ref{F},Val{F}}, D<:Union{Ref{F},Val{F}}, E<:Union{Ref{F},Val{F}}, G<:Union{Ref{F},Val{F}}}, } where F @test Base.code_typed_by_type(tt) isa Vector end @test !(Tuple{Union{Int16,Int8},Ref{Int16},Ref{Int16}} <: Tuple{<:Union{S,T},Ref{S},Ref{T}} where {S,T}) @test !(Tuple{Ref{Int16},Ref{Int16},Union{Int16,Int8}} <: Tuple{Ref{S},Ref{T},<:Union{S,T}} where {S,T}) @test Tuple{NTuple{2,Int}, Int8} <: Tuple{<:Union{NTuple{2,T},Tuple{S,T}}, <:T} where {S,T>:Int} # Variant of the above where T also appears in a non-traversed (inactive) Union # branch — body_occurs_inv(T) is structurally 1 even though dynamic occurs_inv # stays 0, exercising the static-`body_occurs_inv` check in env_unchanged. @test Tuple{NTuple{2,Int}, Int8} <: Tuple{<:Union{NTuple{2,T},Tuple{S,T},Ref{T}}, <:T} where {S,T>:Int} # An unused typevar in a method signature's `where` clause must be # reported in env at its declared index, not dropped or shifted. @test_warn "declares type variable pad but does not use it" @eval f61634(::Type{TW}, ::AbstractArray{T,N}) where {N, T, TW<:Real, pad} = T let sig = methods(f61634)[1].sig _, env = intersection_env(Tuple{typeof(f61634), Type, Vector}, sig) unwrap(e) = e isa Core.SimpleVector ? e[1] : e @test env[1] === 1 @test unwrap(env[2]) isa TypeVar && unwrap(env[2]).name === :T @test unwrap(env[3]) isa TypeVar && unwrap(env[3]).name === :TW @test unwrap(env[4]) isa TypeVar && unwrap(env[4]).name === :pad end # Same issue but with the unused typevar in the middle — exercises the wrong-index # case where dropping the inner UnionAll would shift later typevars to the wrong slot. @test_warn "declares type variable pad but does not use it" @eval g61634(::Type{TW}, ::AbstractArray{T,N}) where {N, pad, TW<:Real, T} = T let sig = methods(g61634)[1].sig, N_var = sig.var # Force a rename of `b`'s outer typevar by sharing its identity with `x`, # which is what causes `inst_type_w_` to rebuild the body and (without the # fix) drop the unused inner UnionAll for `pad`. x = UnionAll(N_var, Tuple{typeof(g61634), Type, AbstractArray{Int, N_var}}) _, env = intersection_env(x, sig) unwrap(e) = e isa Core.SimpleVector ? e[1] : e @test unwrap(env[1]) isa TypeVar && unwrap(env[1]).name === :N @test unwrap(env[2]) isa TypeVar && unwrap(env[2]).name === :pad @test unwrap(env[3]) isa TypeVar && unwrap(env[3]).name === :TW @test env[4] === Int end abstract type _Abs61634a{T,N,U} <: AbstractArray{Union{T,U}, N} end abstract type _Abs61634b{T,F,N} <: AbstractArray{Union{T,F}, N} end mutable struct _Sub61634b{T,F} <: _Abs61634b{T,F,2} end @test eltype(_Abs61634a) === Any @test eltype(_Sub61634b{Float64}) === Any # TypeVar constrainedness quality let e = only(intersection_env(Tuple{Ref}, Tuple{Ref{T}} where T)[2]) @test e isa Core.SimpleVector && e[1] isa TypeVar && e[2] end let e = only(intersection_env(Tuple{Real}, Tuple{T} where T)[2]) @test e isa Core.SimpleVector && e[1] isa TypeVar && e[2] end let e = only(intersection_env(Tuple{Real}, Tuple{T} where T >: Int)[2]) @test e isa Core.SimpleVector && e[1] isa TypeVar && !e[2] end # A fixed tuple prefix before a free vararg length guarantees a matching # right-side tuple element exists, but range and maybe-empty tuple tails do not. let rhs = Tuple{typeof(intersection_env), Type{<:Tuple{Vararg{E}}}} where E fixed_prefix = only(intersection_env(Tuple{typeof(intersection_env), Type{Tuple{Int, Vararg{Int, N}}}} where N, rhs)[2]) maybe_empty = only(intersection_env(Tuple{typeof(intersection_env), Type{Tuple{Vararg{Int, N}}}} where N, rhs)[2]) range_arg = only(intersection_env(Tuple{typeof(intersection_env), Type{<:Tuple{Int}}}, rhs)[2]) fixed_rhs = Tuple{typeof(intersection_env), Type{<:Tuple{E}}} where E exact_fixed = only(intersection_env(Tuple{typeof(intersection_env), Type{Tuple{Int}}}, fixed_rhs)[2]) fixed_range = only(intersection_env(Tuple{typeof(intersection_env), Type{<:Tuple{Int}}}, fixed_rhs)[2]) @test fixed_prefix isa Core.SimpleVector && fixed_prefix[1] isa TypeVar && fixed_prefix[2] @test maybe_empty isa Core.SimpleVector && maybe_empty[1] isa TypeVar && !maybe_empty[2] @test range_arg isa Core.SimpleVector && range_arg[1] isa TypeVar && !range_arg[2] @test exact_fixed isa Core.SimpleVector && exact_fixed[1] isa TypeVar && exact_fixed[2] @test fixed_range isa Core.SimpleVector && fixed_range[1] isa TypeVar && !fixed_range[2] end # Env entries must not introduce a fresh `newvar<:vb.lb` wrapper when `vb.lb` # is already a TypeVar. The doubled `where T<:T_outer where T_outer` pattern # that wrapper would produce accumulates across nested intersections and # triggers exponential-time substitution in `inst_type_w_`. Instead, the env # entry should reference the existing TypeVar directly. let (_, env) = intersection_env(Tuple{P, P} where P, Tuple{P, Q} where {Q, P}) for e in env if e isa Core.SimpleVector inner = e[1] if inner isa TypeVar # Inner's ub must not be a TypeVar (no doubled bound chain). @test !(inner.ub isa TypeVar) end end end end # This one is tricky - because the `E` is outside the `<:` and the diagonal rule applies, # the RHS quantifies over varargs of concrete types and `Tuple{Vararg{T}}` is not one of those. @test !isa(Tuple{Vararg{T}} where T <: Integer, Type{X} where X<:Tuple{Vararg{E}} where E) # TypeVar matching needs to distinguish these two cases @test Type{Ref{A} where A} <: Type{Ref{B} where B<:U} where U @test !((Type{Ref{A} where A} where L) <: (Type{Ref{A}} where A)) # issue #61242: free TypeVars are singleton-like by identity, not stand-ins for # their bounds or their enclosing UnionAll. @test Vector.body != Vector @test Vector.body <: Vector @test !(Vector <: Vector.body) @test typeintersect(Vector.body, Vector) == Vector.body @test typeintersect(Vector.body, Vector{Int}) === Union{} let S = TypeVar(:S, Union{}, Number) @test typeintersect(Union{S, String}, Number) === Union{} @test typeintersect(Union{S, Int}, Number) === Int end # issue #61876: a DataType with a bounded free TypeVar in a bounded parameter # slot is not a subtype of the wrapper. The unrestricted `<:Any` wrapper case is # accepted by convention, but bounded wrappers require an actual type parameter. abstract type Wrapper61876{X<:Real} end struct Sub61876A{T<:Real} <: Wrapper61876{T} end struct Sub61876B{T<:Real} <: Wrapper61876{T} end @test !(Sub61876A.body <: Wrapper61876) @test typejoin(Sub61876A, Sub61876B) <: Wrapper61876 # issue #61876: typeintersect with an innervar whose bound references the # outer var previously triggered `assert(btemp->root != vb)` in finish_unionall. struct B61876{T,N,R} <: AbstractArray{T,N} end struct N61876{T,F} end typeintersect(Tuple{typeof(convert), Type{<:AbstractArray{<:N61876{T,N}} where N where T}, Vector}, Tuple{typeof(convert), Type{B61876{T1,N,R} where {N, R<:(AbstractArray{<:AbstractArray{T1,N},N})}}, AbstractArray{T2,N}} where {T1,T2,N}) # issue #61917: an existential var inside an invariant constructor must not be # equated with an outer universal var whose bound is disjoint, e.g. `Ref{Ref{Bar}}` # inhabits the LHS but not the RHS, so the `UnionAll`s are not in a subtype relation. struct Foo61917; end struct Bar61917; end @test !((Ref{Ref{U}} where U<:Bar61917) <: (Ref{Union{Ref{T}, Ref{U}}} where {T<:Foo61917, U<:Bar61917})) @test !((Ref{Ref{U}} where U<:Integer) <: (Ref{Union{Ref{T}, Ref{U}}} where {T<:AbstractString, U<:Integer})) # a collapsible union is still a supertype @test (Ref{Ref{U}} where U<:Bar61917) <: (Ref{Union{Ref{T}, Ref{U}}} where {T<:Bar61917, U<:Bar61917}) # the internal `Intersect` meet node used to fix this must never escape into a # user-visible result type let r = typeintersect((Ref{Ref{U}} where U<:Bar61917), (Ref{Union{Ref{T}, Ref{U}}} where {T<:Foo61917, U<:Bar61917})) @test !occursin("Intersect", string(r)) @test r == Ref{Ref{Union{}}} end # issue #61917: the `Intersect` meet node can also reach the intersection result # (via a `where S>:T` lower bound); it must be over-approximated, not leaked. let A = AbstractVector{<:Signed}, B = AbstractArray{Int} r = typeintersect(Ref{B}, (Ref{S} where S>:T) where T<:A) @test !occursin("Intersect", string(r)) @test Ref{AbstractArray{Int}} <: r # sound over-approximation of the meet end # The `Intersect` meet node must be respected by subtype queries that take the # no-free-typevars fast path. let A = Tuple{T,T} where T <: Real B = Tuple{Integer,Integer} C = Tuple{Int,Int} X = Tuple{Ref{B}, Ref{C}} Y = Tuple{Ref{S}, Ref{T}} where {T <: A, S >: T} @test C <: A @test C <: B @test X <: Y end # PR #61915: `concrete_min` must treat a `Type{T}` (`TypeEq`) element as # contributing no fixed concrete type, so the covariant-tuple diagonal rule in # `obvious_subtype` does not wrongly reject a `Tuple` of `Type{}`s against a # diagonal `Vararg`. Previously `obvious_subtype` returned a definitive # not-subtype that disagreed with full subtyping, tripping `assert` in subtype.c. # under `==`-class semantics (#33136) the diagonal `Vararg` no longer admits # mixed-tag element pairs: `Type{Int}`'s members include `UnionAll` spellings # of `Int` alongside the `DataType`, and no concrete `T` contains both kinds, # so these are not subtypes anymore; `obvious_subtype` must agree (it used to # widen the elements to their tags) and the intersection must stay nonempty # (the all-`DataType`-tagged pairs remain). function obvious_subtype_33136(x, y) obv = Ref{Cint}(0) r = ccall(:jl_obvious_subtype, Cint, (Any, Any, Ref{Cint}), x, y, obv) return r == 0 ? nothing : obv[] == 1 end let X = Tuple{Union{Type{Int}, Type{Vector{T}} where T}, Type{Int}}, Y = (Tuple{Vararg{T}} where T) @test !(X <: Y) @test obvious_subtype_33136(X, Y) !== true @test typeintersect(X, Y) != Union{} @test typeintersect(Y, X) != Union{} end let X = Tuple{Union{Type{Int}, Type{Vector{T}} where T}, Union{Type{Int}, Type{Vector{T}} where T}}, Y = (Tuple{Vararg{T}} where T) @test !(X <: Y) @test obvious_subtype_33136(X, Y) !== true @test typeintersect(X, Y) != Union{} end # issue #62174: envout for tuple element matching must preserve TypeVar # identities in hoisted bounds. struct P62174{X} end struct M62174{D,F,V<:P62174{D},A<:P62174{F}} end let X = Tuple{Vector{M62174{D,F,V,A}} where {D,F,V<:P62174{D},A<:P62174{F}}}, Y = Tuple{Vector{T}} where T _, env = intersection_env(X, Y) v = env[1][1] p = v.parameters @test p[3].ub.parameters[1] === p[1] @test p[4].ub.parameters[1] === p[2] end # Hoisted union-split of a `∀` variable's upper bound: a left-side `where` var # with trivial lower bound, a union upper bound, and only covariant occurrences # in the body distributes over the arms of its bound. @test (Tuple{T,T} where T<:Union{Float64,Int64}) <: Union{Tuple{Float64,Float64},Tuple{Int64,Int64}} @test Union{Tuple{Float64,Float64},Tuple{Int64,Int64}} == (Tuple{T,T} where T<:Union{Float64,Int64}) @test (Tuple{T,T} where T<:Union{Integer,AbstractString}) <: Union{Tuple{Integer,Integer},Tuple{AbstractString,AbstractString}} @test (Tuple{T,T} where T<:Union{Int8,Int16,Int32,Int64}) <: Union{Tuple{Int8,Int8},Tuple{Int16,Int16},Tuple{Int32,Int32},Tuple{Int64,Int64}} @test (Tuple{Vararg{T}} where T<:Union{Float64,Int64}) <: Union{Tuple{Vararg{Float64}},Tuple{Vararg{Int64}}} @test (Tuple{Vararg{T}} where T<:Union{Integer,AbstractString}) <: Union{Tuple{Vararg{Integer}},Tuple{Vararg{AbstractString}}} # the split must not apply to a variable that also occurs invariantly @test !((Tuple{T,Ref{T}} where T<:Union{Int64,String}) <: Union{Tuple{Int64,Ref{Int64}},Tuple{String,Ref{String}}}) # ... and must not change the `∃` (right) side @test Vector{Union{Int64,String}} <: (Vector{T} where T<:Union{Int64,String}) # obvious_subtype must definitively reject `X <: Type{T}` (Type{} is a TypeEq, not a DataType) let rejects(@nospecialize(x), @nospecialize(y)) = (r = Ref{Cint}(2); ccall(:jl_obvious_subtype, Cint, (Any,Any,Ptr{Cint}), x, y, r) != 0 && r[] == 0) @test rejects(Tuple{typeof(sin)}, Tuple{Type{T}} where T) @test rejects(Int, Type{T} where T) @test rejects(Int, Type{Int}) @test rejects(String, Type{Int}) end # `TypeEgal{T}`: the egality-based dual of `Type{T}`, whose only instance is `T` # itself (`===`); free typevars are disallowed _typeegal_id(::Type{T}) where {T} = T @testset "TypeEgal" begin TE = Core.TypeEgal # membership is by egality (`===`), not type equality @test isa(Int, TE{Int}) @test !isa(Integer, TE{Int}) @test !isa(Int, TE{Integer}) @test isa(Vector, TE{Vector}) @test isa(Union{Int,String}, TE{Union{Int,String}}) @test_throws TypeError TE{:a} @test_throws TypeError TE{1} # egal implies equal, but not the reverse @test TE{Int} <: Type{Int} @test !(Type{Int} <: TE{Int}) @test TE{Int} <: TE{Int} @test !(TE{Int} <: TE{Integer}) @test !(TE{Integer} <: TE{Int}) @test TE{Int} <: Core.TypeEq{Int} @test TE{Int} != Type{Int} @test TE{Int} !== Type{Int} # a `TypeEgal{T}` dispatches as the singleton `typeof(T)` @test TE{Int} <: DataType @test !(TE{Int} <: UnionAll) @test TE{Vector} <: UnionAll @test TE{Int} <: Any @test TE{Int} <: Type @test TE{Int} <: Core.AnyType # nothing but `Union{}` and egal `TypeEgal`s is a subtype of `TypeEgal{T}` @test !(DataType <: TE{Int}) @test !(Type{Int} <: TE{Int}) @test Union{} <: TE{Int} @test Base.iskindtype(TE) # free typevars are disallowed inside `TypeEgal`, but closed parameters are fine @test_throws TypeError TE{TypeVar(:T)} @test isa(TE{Vector{S} where S}, TE) @test isa(Vector{S} where S, TE{Vector{S} where S}) # intersection keeps the more-specific `TypeEgal`; wrappers are freshly # allocated, so compare by mutual subtyping tyeq(@nospecialize(a), @nospecialize(b)) = a <: b && b <: a @test tyeq(typeintersect(TE{Int}, Type{Int}), TE{Int}) @test tyeq(typeintersect(Type{Int}, TE{Int}), TE{Int}) @test tyeq(typeintersect(TE{Int}, DataType), TE{Int}) @test typeintersect(TE{Int}, Type{Integer}) === Union{} @test tyeq(typeintersect(TE{Int}, TE{Int}), TE{Int}) @test typeintersect(TE{Int}, TE{Integer}) === Union{} @test tyeq(typeintersect(TE{Int}, (Type{T} where T)), TE{Int}) @test tyeq(typeintersect(TE{Int}, Any), TE{Int}) # the dispatch cache specializes type-valued arguments through `TypeEgal` @test _typeegal_id(Int) === Int @test _typeegal_id(Vector) === Vector @test _typeegal_id(Union{Int,String}) === Union{Int,String} # An egal-pinned (dispatch-tuple) query pins sparams by identity even when # they bind through a nested equality wrapper (`Type{<:Type{Val{S}}}`): the # bound being consistency-checked is a concrete type object, not an # argument-slot spelling, so its structural descent keeps identity. An # `==`-only `Type`-slotted query must still produce a pinned uncertainty # marker (`svec(tvar, constrained)`). let sig = Tuple{Type{<:Type{Val{S}}}, Type{<:Type{Val{f}}}} where {S,f} X = Tuple{Tuple{Int}} _, E = intersection_env(Tuple{TE{Type{Val{X}}}, TE{Type{Val{:x}}}}, sig) @test E[1] === X @test E[2] === :x _, E = intersection_env(Tuple{Type{Type{Val{X}}}, TE{Type{Val{:x}}}}, sig) @test E[1] isa Core.SimpleVector let tv = E[1][1]::TypeVar @test tv.lb === tv.ub === X && E[1][2] === true end @test E[2] === :x end # a bare argument value seen through an equality wrapper is only # `==`-authoritative for the spelling of a binding: it must not displace # the canonical spelling pinned by an invariant (type-tag) position, in # either recording order let W = Union{S1,S2} where {S1<:Int,S2<:Int} @test W == Int && W !== Int _, E = intersection_env(Tuple{Ref{Int}, TE{W}}, Tuple{Ref{T}, Type{T}} where T) @test E[1] === Int _, E = intersection_env(Tuple{TE{W}, Ref{Int}}, Tuple{Type{T}, Ref{T}} where T) @test E[1] === Int # with no canonical contributor, the value's own spelling binds _, E = intersection_env(Tuple{TE{W}}, Tuple{Type{T}} where T) @test E[1] === W end # LHS union branches that pin a variable through different certainty # spellings (an `==`-pinned marker from the `Type{Int}` branch, a plain # value from the `Int` branch) agree on the binding and must merge to the # weaker (marker) spelling, not degrade the variable to unbound let env = Any[nothing] GC.@preserve env begin r = ccall(:jl_subtype_env, Cint, (Any, Any, Ptr{Any}, Cint), Tuple{Union{Type{Int}, Int}}, Tuple{Union{Type{T}, T}} where {T}, env, 1) @test r == 1 sp = env[1] if sp isa Core.SimpleVector tv = sp[1]::TypeVar @test tv.lb === Int && tv.ub === Int && sp[2] === true else @test sp === Int end end end end # issues #33136 / #62141: `Type{T} <: S` iff every `U == T` satisfies `isa(U, S)`. # The members of `Type{T}` straddle several kinds (`Tuple{S} where S<:Int` is a # `UnionAll` spelling of `Tuple{Int}`), so a `Type{T}` never lies in a single # kind, but does lie in the union of the kinds its class can inhabit. @testset "Type{T} vs kinds soundness (#33136, #62141)" begin # the #62141 contradiction: `Type{Union{}} isa Type{Type{Union{}}}` but # `Type{Union{}}` is not a `DataType`, so `Type{Type{Union{}}} <: DataType` # must not hold @test Type{Union{}} isa Type{Type{Union{}}} @test !(Type{Union{}} isa DataType) @test !(Type{Type{Union{}}} <: DataType) # ... and the analogous witness-based contradiction for `Tuple{Int}` let u = Tuple{S} where S<:Int @test u isa Type{Tuple{Int}} @test !(u isa DataType) @test !(Type{Tuple{Int}} <: DataType) @test u isa UnionAll @test Type{Tuple{Int}} <: Union{DataType,UnionAll} end # `Union{UnionAll, DataType}` is the smallest kind cover for `Type{Int}` @test !(Type{Int} <: DataType) @test !(Type{Int} <: UnionAll) @test Type{Int} <: Union{DataType,UnionAll} @test !(Type{Int} <: Union{DataType,Union}) # a `Type{T'}` union component covers all of `Type{T}` (when `T' == T`) or # nothing, and mixes with kind components @test Type{Int} <: Union{String,Type{Int}} @test Type{Int} <: Union{DataType,Type{Int}} @test !(Type{Int} <: Union{DataType,Type{String}}) # abstract and zero-parameter classes are treated uniformly @test !(Type{Integer} <: DataType) @test Type{Integer} <: Union{DataType,UnionAll} @test !(Type{Any} <: DataType) # tuples with (semantically) union or vararg parameters also have `Union` # spellings: `Tuple{Union{Int,String}} == Union{Tuple{Int},Tuple{String}}`, # `Tuple{Vararg{Int}} == Union{Tuple{}, Tuple{Int,Vararg{Int}}}` @test !(Type{Tuple{Union{Int,String}}} <: Union{DataType,UnionAll}) @test Type{Tuple{Union{Int,String}}} <: Union{DataType,UnionAll,Union} @test !(Type{Tuple{Vararg{Int}}} <: Union{DataType,UnionAll}) @test Type{Tuple{Vararg{Int}}} <: Union{DataType,UnionAll,Union} # unions of non-Tuples have no `DataType` spelling @test Type{Union{Int,String}} <: Union{Union,UnionAll} @test !(Type{Union{Int,String}} <: Union) # wrapper-like `UnionAll`s have neither `DataType` nor `Union` spellings @test Type{Vector} <: UnionAll @test Type{Pair} <: UnionAll @test !(Type{Union{}} <: UnionAll) # instantiated parametric classes have `UnionAll` spellings # (`Vector{S} where Int<:S<:Int`) @test !(Type{Vector{Int}} <: DataType) @test Type{Vector{Int}} <: Union{DataType,UnionAll} @test !((Type{Vector{T}} where T) <: DataType) @test (Type{Vector{T}} where T) <: Union{DataType,UnionAll} # an unbound var can instantiate to `Union{}` (collapsing a Tuple to the # bottom class) or to a union (splitting it), so the open `Tuple{T}` class # needs `TypeofBottom` and `Union` in its cover as well @test !((Type{Tuple{T}} where T) <: Union{DataType,UnionAll}) @test (Type{Tuple{T}} where T) <: Union{DataType,UnionAll,Union,Core.TypeofBottom} # `Type`-of-`Type` classes are `TypeEq`-kinded plus `UnionAll` spellings @test !(Type{Type{Int}} <: Core.TypeEq) @test Type{Type{Int}} <: Union{Core.TypeEq,UnionAll} # ... except `Type` itself, whose class also contains the `AnyType` DataType @test !(Type{Type} <: Union{Core.TypeEq,UnionAll}) @test Type{Type} <: Union{Core.TypeEq,UnionAll,DataType} # the `Union{}` class stays exempt: the runtime keeps the bottom object # unique, so `Type{Union{}} == TypeofBottom` remains an equality @test Type{Union{}} == Core.TypeofBottom @test Type{Union{}} <: Core.TypeofBottom @test Core.TypeofBottom <: Type{Union{}} @test Type{Union{}} <: Union{Core.TypeofBottom,UnionAll} @test !(Type{Core.TypeofBottom} <: DataType) @test Type{Core.TypeofBottom} <: Union{DataType,Core.TypeEq,UnionAll} # `TypeEgal{T}` pins its sole member by identity, so it does lie in the # single kind `typeof(T)` @test Core.TypeEgal{Int} <: DataType @test Core.TypeEgal{Vector} <: UnionAll @test !(Core.TypeEgal{Int} <: UnionAll) # intersections with kinds are no longer (unsoundly) empty @test typeintersect(Type{Int}, UnionAll) == Type{Int} @test typeintersect(Type{Int}, DataType) == Type{Int} @test typeintersect(Type{Int}, Union) == Union{} @test typeintersect(Type{Vector}, DataType) == Union{} @test typeintersect(Type{Vector}, UnionAll) == Type{Vector} @test typeintersect(Type{Union{Int,String}}, Union) == Type{Union{Int,String}} @test typeintersect(Type{Union{Int,String}}, DataType) == Union{} @test typeintersect(Type{Int}, Core.AnyType) == Type{Int} # union construction must not absorb `Type{T}` into a kind @test Union{Type{Int},DataType} isa Union @test (Union{Type{Vector{T}},DataType} where T) isa UnionAll # dispatch: methods on `Type{Int}` still beat methods on kinds @test Base.morespecific(Tuple{Type{Int}}, Tuple{DataType}) # the equal spellings from the original #33136 report behave alike, also on # queries only the kind cover can answer (a typevar pinned by equal bounds # ranges over one `==`-class) @test (Type{T} where DataType<:T<:DataType) == Type{DataType} @test !((Type{T} where DataType<:T<:DataType) <: DataType) @test !(Type{DataType} <: DataType) @test (Type{T} where DataType<:T<:DataType) <: Union{DataType,UnionAll} @test Type{DataType} <: Union{DataType,UnionAll} @test (Type{T} where Int<:T<:Int) <: Union{DataType,UnionAll} @test !((Type{T} where Int<:T<:Int) <: DataType) @test typeintersect(Type{T} where Int<:T<:Int, UnionAll) != Union{} # bounds that pin only up to `==` (not `===`) denote a single class too @test (Type{T} where Tuple{Int}<:T<:(Tuple{S} where S<:Int)) == Type{Tuple{Int}} @test !((Type{T} where Tuple{Int}<:T<:(Tuple{S} where S<:Int)) <: DataType) @test (Type{T} where Tuple{Int}<:T<:(Tuple{S} where S<:Int)) <: Union{DataType,UnionAll} # a dangling-typevar `Type{v}` is an internal single-object dispatch key, # pinned to its type tag let T = TypeVar(:T) @test Type{Ref{T}} <: DataType @test !(Type{Ref{T}} <: UnionAll) end # the kind cover also applies over the closed components of a union that # additionally carries typevars @test Tuple{Type{Int}, Ref{Int}} <: (Tuple{Union{DataType,UnionAll,T}, Ref{T}} where T) # the diagonal rule must not widen a `Type{T}` lower bound to its tag: no # concrete type contains all members of `Type{Tuple{Int}}` and `String` @test !(Tuple{Type{Tuple{Int}}, DataType} <: (Tuple{T,T} where T)) @test Tuple{Core.TypeEgal{Int}, Core.TypeEgal{String}} <: (Tuple{T,T} where T) let u2 = Tuple{S} where S<:Int # == Tuple{Int}, but a UnionAll K = Tuple{Core.TypeEgal{u2}, Core.TypeEgal{String}} A = Tuple{Type{Tuple{Int}}, DataType} @test K <: A @test !(K <: (Tuple{T,T} where T)) # so A <: (Tuple{T,T} where T) must fail too end # the bare-`Type` RHS fast path must not skip the envout binding let env = Any[nothing] GC.@preserve env begin @test ccall(:jl_subtype_env, Cint, (Any, Any, Ptr{Any}, Cint), Type{Int}, Type, env, 1) == 1 @test env[1] !== nothing end end end