diff --git a/src/subtype.c b/src/subtype.c index baf5a91b11899..8a3300cad8bac 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -1072,7 +1072,7 @@ static int subtype_tuple_tail(struct subtype_tuple_env *env, int8_t R, jl_stenv_ // an identical type on the left doesn't need to be compared to a Vararg // element type on the right more than twice. } - else if (x_same && + else if (x_same && e->Runions.depth == 0 && ((yi == env->lasty && !jl_has_free_typevars(xi) && !jl_has_free_typevars(yi)) || (yi == env->lasty && !env->vx && env->vy && jl_is_concrete_type(xi)))) { // fast path for repeated elements diff --git a/test/subtype.jl b/test/subtype.jl index 47026df924d3b..c99fc780799e6 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1847,3 +1847,17 @@ let A = Tuple{T, Ref{T}, T} where {T}, @test_broken I <: A @test_broken I <: B 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())