diff --git a/src/subtype.c b/src/subtype.c index b4ddb8f0c1de5..153eed2648c70 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -3032,6 +3032,14 @@ static jl_value_t *intersect_types(jl_value_t *x, jl_value_t *y, int emptiness_o jl_stenv_t e; if (obviously_disjoint(x, y, 0)) return jl_bottom_type; + if (jl_is_dispatch_tupletype(x) || jl_is_dispatch_tupletype(y)) { + if (jl_subtype(x, y)) + return x; + else if (jl_subtype(y, x)) + return y; + else + return jl_bottom_type; + } init_stenv(&e, NULL, 0); e.intersection = e.ignore_free = 1; e.emptiness_only = emptiness_only; diff --git a/test/subtype.jl b/test/subtype.jl index a8b00b57cc2f1..99f3e8fb21c50 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1632,3 +1632,22 @@ 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 +@test_broken typeintersect(Tuple{Vector{Vector{Float32}},Matrix,Matrix}, + Tuple{Vector{V},Matrix{Int},Matrix{S}} where {S, V<:AbstractVector{S}}) == + Tuple{Array{Array{Float32,1},1},Array{Int,2},Array{Float32,2}}