Skip to content

Commit 4991eb8

Browse files
N5N3KristofferC
authored andcommitted
typeintersect: fix triangular vars handling outside constructor. (#58018)
Fix #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.) (cherry picked from commit ec424d4)
1 parent bedac2c commit 4991eb8

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/subtype.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,7 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13821382
x = pick_union_element(x, e, 0);
13831383
}
13841384
if (jl_is_uniontype(y)) {
1385-
if (x == ((jl_uniontype_t*)y)->a || x == ((jl_uniontype_t*)y)->b)
1385+
if (obviously_in_union(y, x))
13861386
return 1;
13871387
if (jl_is_unionall(x))
13881388
return subtype_unionall(y, (jl_unionall_t*)x, e, 0, param);
@@ -2528,9 +2528,6 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e,
25282528

25292529
static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t *e, int8_t R, int param)
25302530
{
2531-
// band-aid for #56040
2532-
if (!jl_is_uniontype(x) && obviously_in_union((jl_value_t *)u, x))
2533-
return x;
25342531
int no_free = !jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u);
25352532
if (param == 2 || no_free) {
25362533
jl_value_t *a=NULL, *b=NULL;
@@ -2667,7 +2664,7 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
26672664
// subtype, treating all vars as existential
26682665
static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
26692666
{
2670-
if (x == jl_bottom_type || y == (jl_value_t*)jl_any_type)
2667+
if (x == jl_bottom_type || y == (jl_value_t*)jl_any_type || obviously_in_union(y, x))
26712668
return 1;
26722669
int8_t *rs = (int8_t*)alloca(current_env_length(e));
26732670
jl_varbinding_t *v = e->vars;
@@ -2790,7 +2787,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27902787
jl_value_t *ub = R ? intersect_aside(a, bb->ub, e, bb->depth0) : intersect_aside(bb->ub, a, e, bb->depth0);
27912788
if (ub == jl_bottom_type)
27922789
return jl_bottom_type;
2793-
if (bb->constraintkind == 1 || e->triangular) {
2790+
if (bb->constraintkind == 1 || (e->triangular && param == 1)) {
27942791
if (e->triangular && check_unsat_bound(ub, b, e))
27952792
return jl_bottom_type;
27962793
set_bound(&bb->ub, ub, b, e);
@@ -4105,12 +4102,14 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
41054102
if (jl_subtype(y, x)) return y;
41064103
}
41074104
if (jl_is_uniontype(x)) {
4108-
if (y == ((jl_uniontype_t*)x)->a || y == ((jl_uniontype_t*)x)->b)
4105+
if (obviously_in_union(x, y))
41094106
return y;
4107+
if (jl_is_uniontype(y) && obviously_in_union(y, x))
4108+
return x;
41104109
return intersect_union(y, (jl_uniontype_t*)x, e, 0, param);
41114110
}
41124111
if (jl_is_uniontype(y)) {
4113-
if (x == ((jl_uniontype_t*)y)->a || x == ((jl_uniontype_t*)y)->b)
4112+
if (obviously_in_union(y, x))
41144113
return x;
41154114
if (jl_is_unionall(x) && (jl_has_free_typevars(x) || jl_has_free_typevars(y)))
41164115
return intersect_unionall(y, (jl_unionall_t*)x, e, 0, param);

test/subtype.jl

Lines changed: 13 additions & 2 deletions
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)