Skip to content

Commit ec424d4

Browse files
authored
typeintersect: fix triangular vars handling outside constructor. (JuliaLang#58018)
Fix JuliaLang#57852. The 'e->triangle' branch doesn't make sense for variables outside the constructor. Let pkgeval tell us if `constraintkind` based branches are suitable for handling them. (The second commit is needed to fix some stack overflow regression.)
2 parents e542818 + 2b8a05c commit ec424d4

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/subtype.c

+7-8
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13931393
x = pick_union_element(x, e, 0);
13941394
}
13951395
if (jl_is_uniontype(y)) {
1396-
if (x == ((jl_uniontype_t*)y)->a || x == ((jl_uniontype_t*)y)->b)
1396+
if (obviously_in_union(y, x))
13971397
return 1;
13981398
if (jl_is_unionall(x))
13991399
return subtype_unionall(y, (jl_unionall_t*)x, e, 0, param);
@@ -2539,9 +2539,6 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e,
25392539

25402540
static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t *e, int8_t R, int param)
25412541
{
2542-
// band-aid for #56040
2543-
if (!jl_is_uniontype(x) && obviously_in_union((jl_value_t *)u, x))
2544-
return x;
25452542
int no_free = !jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u);
25462543
if (param == 2 || no_free) {
25472544
jl_value_t *a=NULL, *b=NULL;
@@ -2678,7 +2675,7 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
26782675
// subtype, treating all vars as existential
26792676
static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
26802677
{
2681-
if (x == jl_bottom_type || y == (jl_value_t*)jl_any_type)
2678+
if (x == jl_bottom_type || y == (jl_value_t*)jl_any_type || obviously_in_union(y, x))
26822679
return 1;
26832680
int8_t *rs = (int8_t*)alloca(current_env_length(e));
26842681
jl_varbinding_t *v = e->vars;
@@ -2801,7 +2798,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
28012798
jl_value_t *ub = R ? intersect_aside(a, bb->ub, e, bb->depth0) : intersect_aside(bb->ub, a, e, bb->depth0);
28022799
if (ub == jl_bottom_type)
28032800
return jl_bottom_type;
2804-
if (bb->constraintkind == 1 || e->triangular) {
2801+
if (bb->constraintkind == 1 || (e->triangular && param == 1)) {
28052802
if (e->triangular && check_unsat_bound(ub, b, e))
28062803
return jl_bottom_type;
28072804
set_bound(&bb->ub, ub, b, e);
@@ -4116,12 +4113,14 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
41164113
if (jl_subtype(y, x)) return y;
41174114
}
41184115
if (jl_is_uniontype(x)) {
4119-
if (y == ((jl_uniontype_t*)x)->a || y == ((jl_uniontype_t*)x)->b)
4116+
if (obviously_in_union(x, y))
41204117
return y;
4118+
if (jl_is_uniontype(y) && obviously_in_union(y, x))
4119+
return x;
41214120
return intersect_union(y, (jl_uniontype_t*)x, e, 0, param);
41224121
}
41234122
if (jl_is_uniontype(y)) {
4124-
if (x == ((jl_uniontype_t*)y)->a || x == ((jl_uniontype_t*)y)->b)
4123+
if (obviously_in_union(y, x))
41254124
return x;
41264125
if (jl_is_unionall(x) && (jl_has_free_typevars(x) || jl_has_free_typevars(y)))
41274126
return intersect_unionall(y, (jl_unionall_t*)x, e, 0, param);

test/subtype.jl

+13-2
Original file line numberDiff line numberDiff line change
@@ -2087,8 +2087,7 @@ let A = Tuple{Any, Type{Ref{_A}} where _A},
20872087
I = typeintersect(A, B)
20882088
@test I != Union{}
20892089
@test Tuple{Type{Ref{Integer}}, Type{Ref{Integer}}} <: I
2090-
# TODO: this intersection result seems too wide (I == B) ?
2091-
@test_broken !<:(Tuple{Type{Int}, Type{Int}}, I)
2090+
@test !<:(Tuple{Type{Int}, Type{Int}}, I)
20922091
end
20932092

20942093
@testintersect(Tuple{Type{T}, T} where T<:(Tuple{Vararg{_A, _B}} where _B where _A),
@@ -2757,3 +2756,15 @@ end
27572756
Pair{N, T} where {N,NTuple{N,Int}<:T<:Tuple{Int,Vararg{Int}}},
27582757
!Union{}
27592758
)
2759+
2760+
#issue 57852
2761+
@testintersect(
2762+
Tuple{Type{T}, Type{<:F}, Type{<:F}} where {T, F<:Union{String, T}},
2763+
Tuple{Type{Complex{T}} where T, Type{Complex{T}} where T, Type{String}},
2764+
Tuple{Type{Complex{T}}, Type{Complex{T}}, Type{String}} where T
2765+
)
2766+
@testintersect(
2767+
Tuple{Type{T}, Type{<:Union{F, Nothing}}, Type{<:Union{F, Nothing}}} where {T, F<:Union{String, T}},
2768+
Tuple{Type{Complex{T}} where T, Type{Complex{T}} where T, Type{String}},
2769+
Tuple{Type{Complex{T}}, Type{Complex{T}}, Type{String}} where T
2770+
)

0 commit comments

Comments
 (0)