From a9ad6c2bb5771e54a3d4505e2d3146d280c3b093 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Sat, 6 Jul 2019 11:55:01 -0400 Subject: [PATCH] fix #32488, type intersection regression (#32509) Issue was caused by 74305bf2c43546bf76843b72ff0d268a3fe16920, so this reverts part of the new logic from there. --- src/subtype.c | 23 ++++++++++++++++++++--- test/subtype.jl | 17 +++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index f6516c96a1b1c..0fbe5e809d05b 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -2129,19 +2129,35 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int int d = bb->depth0; jl_value_t *root=NULL; jl_savedenv_t se; if (param == 2) { - if (!(subtype_in_env_existential(bb->lb, a, e, 0, d) && subtype_in_env_existential(a, bb->ub, e, 1, d))) - return jl_bottom_type; - jl_value_t *ub = a; + jl_value_t *ub = NULL; + JL_GC_PUSH2(&ub, &root); + if (!jl_has_free_typevars(a)) { + save_env(e, &root, &se); + int issub = subtype_in_env_existential(bb->lb, a, e, 0, d) && subtype_in_env_existential(a, bb->ub, e, 1, d); + restore_env(e, root, &se); + free(se.buf); + if (!issub) { + JL_GC_POP(); + return jl_bottom_type; + } + ub = a; + } + else { + ub = R ? intersect_aside(a, bb->ub, e, 1, d) : intersect_aside(bb->ub, a, e, 0, d); + // TODO: we should probably check `bb->lb <: ub` here; find a test case for that + } if (ub != (jl_value_t*)b) { if (jl_has_free_typevars(ub)) { // constraint X == Ref{X} is unsatisfiable. also check variables set equal to X. if (var_occurs_inside(ub, b, 0, 0)) { + JL_GC_POP(); return jl_bottom_type; } jl_varbinding_t *btemp = e->vars; while (btemp != NULL) { if (btemp->lb == (jl_value_t*)b && btemp->ub == (jl_value_t*)b && var_occurs_inside(ub, btemp->var, 0, 0)) { + JL_GC_POP(); return jl_bottom_type; } btemp = btemp->prev; @@ -2150,6 +2166,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int bb->ub = ub; bb->lb = ub; } + JL_GC_POP(); return ub; } else if (bb->constraintkind == 0) { diff --git a/test/subtype.jl b/test/subtype.jl index 2e03ec3d089f1..8e31d88df50da 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1481,7 +1481,9 @@ CovType{T} = Union{AbstractArray{T,2}, # 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}}}}) + Pair{T, Ref{Tuple{Ref{Ref{Tuple{Int}}},Ref{Float64}}}} where T) +# TODO: should be able to get this result +# Pair{Float64, Ref{Tuple{Ref{Ref{Tuple{Int}}},Ref{Float64}}}} module I31703 using Test, LinearAlgebra @@ -1608,6 +1610,13 @@ end #end # issue #32386 -# TODO: intersect currently returns a bad answer here (it has free typevars) -@test typeintersect(Type{S} where S<:(Array{Pair{_A,N} where N, 1} where _A), - Type{Vector{T}} where T) != Union{} +@test typeintersect(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 + +# 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)