Skip to content

Commit 4a44005

Browse files
committed
fix #30335, regression in intersection of unions of typevars
1 parent 217d330 commit 4a44005

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/subtype.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,12 +1333,17 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e);
13331333
// intersect in nested union environment, similar to subtype_ccheck
13341334
static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int depth)
13351335
{
1336-
jl_value_t *res;
1336+
// band-aid for #30335
1337+
if (x == (jl_value_t*)jl_any_type && !jl_is_typevar(y))
1338+
return y;
1339+
if (y == (jl_value_t*)jl_any_type && !jl_is_typevar(x))
1340+
return x;
1341+
13371342
int savedepth = e->invdepth;
13381343
jl_unionstate_t oldRunions = e->Runions;
13391344
e->invdepth = depth;
13401345

1341-
res = intersect_all(x, y, e);
1346+
jl_value_t *res = intersect_all(x, y, e);
13421347

13431348
e->Runions = oldRunions;
13441349
e->invdepth = savedepth;
@@ -1466,6 +1471,8 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
14661471
return (jl_value_t*)b;
14671472
}
14681473
else if (bb->constraintkind == 2) {
1474+
// TODO: removing this case fixes many test_brokens in test/subtype.jl
1475+
// but breaks other tests.
14691476
if (!subtype_in_env(a, bb->ub, e))
14701477
return jl_bottom_type;
14711478
jl_value_t *lb = simple_join(bb->lb, a);
@@ -1624,6 +1631,10 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
16241631
// you can construct `T{x} where x` even if T's parameter is actually
16251632
// limited. in that case we might get an invalid instantiation here.
16261633
res = jl_substitute_var(res, vb->var, varval);
1634+
// simplify chains of UnionAlls where bounds become equal
1635+
while (jl_is_unionall(res) && obviously_egal(((jl_unionall_t*)res)->var->lb,
1636+
((jl_unionall_t*)res)->var->ub))
1637+
res = jl_instantiate_unionall((jl_unionall_t*)res, ((jl_unionall_t*)res)->var->lb);
16271638
}
16281639
JL_CATCH {
16291640
res = jl_bottom_type;

test/subtype.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,3 +1399,24 @@ end
13991399
@testintersect(Tuple{Pair{Int64,2}, NTuple},
14001400
Tuple{Pair{F,N},Tuple{Vararg{F,N}}} where N where F,
14011401
Tuple{Pair{Int64,2}, Tuple{Int64,Int64}})
1402+
1403+
# issue #30335
1404+
@testintersect(Tuple{Any,Rational{Int},Int},
1405+
Tuple{LT,R,I} where LT<:Union{I, R} where R<:Rational{I} where I<:Integer,
1406+
Tuple{LT,Rational{Int},Int} where LT<:Union{Rational{Int},Int})
1407+
1408+
#@testintersect(Tuple{Any,Tuple{Int},Int},
1409+
# Tuple{LT,R,I} where LT<:Union{I, R} where R<:Tuple{I} where I<:Integer,
1410+
# Tuple{LT,Tuple{Int},Int} where LT<:Union{Tuple{Int},Int})
1411+
# fails due to this:
1412+
let U = Tuple{Union{LT, LT1},Union{R, R1},Int64} where LT1<:R1 where R1<:Tuple{Int64} where LT<:Int64 where R<:Tuple{Int64},
1413+
U2 = Union{Tuple{LT,R,Int64} where LT<:Int64 where R<:Tuple{Int64}, Tuple{LT,R,Int64} where LT<:R where R<:Tuple{Int64}},
1414+
V = Tuple{Union{Tuple{Int},Int},Tuple{Int},Int},
1415+
V2 = Tuple{L,Tuple{Int},Int} where L<:Union{Tuple{Int},Int}
1416+
@test U == U2
1417+
@test U == V
1418+
@test U == V2
1419+
@test V == V2
1420+
@test U2 == V
1421+
@test_broken U2 == V2
1422+
end

0 commit comments

Comments
 (0)