diff --git a/src/subtype.c b/src/subtype.c index c257bcae89393b..4bc5c83a92be75 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -961,6 +961,8 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) if (yy) record_var_occurrence(yy, e, param); if (yr) { if (xx) record_var_occurrence(xx, e, param); + if (xx->lb == jl_bottom_type) + return 1; // allow Bottom <: non-type return subtype(xx->lb, yy->ub, e, 0); } return var_lt((jl_tvar_t*)x, y, e, param); @@ -1779,7 +1781,10 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind jl_tvar_t *newvar = vb->var; JL_GC_PUSH2(&res, &newvar); // try to reduce var to a single value - if (obviously_egal(vb->lb, vb->ub)) { + if (jl_is_long(vb->ub) && jl_is_typevar(vb->lb)) { + varval = vb->ub; + } + else if (obviously_egal(vb->lb, vb->ub)) { // given x<:T<:x, substitute x for T varval = vb->ub; } diff --git a/test/subtype.jl b/test/subtype.jl index d766c49079e1e5..faf9c3de823f19 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1509,3 +1509,23 @@ 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}, + # TODO: this could be narrower + Tuple{Type{SA{2,L}},Type{SA{2,16}}} where L)