Skip to content

Commit ed07e71

Browse files
committed
fix #42409, stack overflow in type intersection
1 parent df52b94 commit ed07e71

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

src/subtype.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,8 @@ static int var_lt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
639639
return 1;
640640
}
641641

642+
static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOTSAFEPOINT;
643+
642644
// check that type var `b` is >: `a`, and update b's lower bound.
643645
static int var_gt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
644646
{
@@ -656,7 +658,10 @@ static int var_gt(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int param)
656658
}
657659
if (!((bb->ub == (jl_value_t*)jl_any_type && !jl_is_type(a) && !jl_is_typevar(a)) || subtype_ccheck(a, bb->ub, e)))
658660
return 0;
659-
bb->lb = simple_join(bb->lb, a);
661+
jl_value_t *lb = simple_join(bb->lb, a);
662+
if (!e->intersection || !subtype_by_bounds(lb, b, e))
663+
bb->lb = lb;
664+
// this bound should not be directly circular
660665
assert(bb->lb != (jl_value_t*)b);
661666
if (jl_is_typevar(a)) {
662667
jl_varbinding_t *aa = lookup(e, (jl_tvar_t*)a);
@@ -2918,7 +2923,7 @@ static jl_value_t *intersect_type_type(jl_value_t *x, jl_value_t *y, jl_stenv_t
29182923

29192924
// cmp <= 0: is x already <= y in this environment
29202925
// cmp >= 0: is x already >= y in this environment
2921-
static int compareto_var(jl_value_t *x, jl_tvar_t *y, jl_stenv_t *e, int cmp)
2926+
static int compareto_var(jl_value_t *x, jl_tvar_t *y, jl_stenv_t *e, int cmp) JL_NOTSAFEPOINT
29222927
{
29232928
if (x == (jl_value_t*)y)
29242929
return 1;
@@ -2938,7 +2943,7 @@ static int compareto_var(jl_value_t *x, jl_tvar_t *y, jl_stenv_t *e, int cmp)
29382943
// Check whether the environment already asserts x <: y via recorded bounds.
29392944
// This is used to avoid adding redundant constraints that lead to cycles.
29402945
// Note this is a semi-predicate: 1 => is a subtype, 0 => unknown
2941-
static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
2946+
static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) JL_NOTSAFEPOINT
29422947
{
29432948
if (!jl_is_typevar(x) || !jl_is_typevar(y))
29442949
return 0;

test/subtype.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,3 +1971,8 @@ end
19711971
@testintersect(Tuple{Type{T}, T} where T<:(Tuple{Vararg{_A, _B}} where _B where _A),
19721972
Tuple{Type{Tuple{Vararg{_A, N}} where _A<:F}, Pair{N, F}} where F where N,
19731973
Bottom)
1974+
1975+
# issue #42409
1976+
@testintersect(Tuple{Type{Pair{_A, S} where S<:AbstractArray{<:_A, 2}}, Dict} where _A,
1977+
Tuple{Type{Pair{_A, S} where S<:AbstractArray{<:_A, 2}} where _A, Union{Array, Pair}},
1978+
Bottom)

0 commit comments

Comments
 (0)