diff --git a/src/subtype.c b/src/subtype.c index 92140944a9aed..4c4244351b5d1 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -2803,6 +2803,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 f8a7c87005edd..bb808ad63d746 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1615,3 +1615,22 @@ end Tuple{Array{Tuple{Vararg{Int64,N}},N},Tuple{Vararg{Array{Int64,1},N}}} where N, Tuple{Array{Tuple{Int64},1}, Tuple}, Tuple{Array{Tuple{Int64},1},Tuple{Array{Int64,1}}}) + +# 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}}