Skip to content

Commit 47bd2ba

Browse files
JeffBezansonKristofferC
authored andcommitted
fix #30335, regression in intersection of unions of typevars (#30353)
(cherry picked from commit 8893aec)
1 parent e8c818f commit 47bd2ba

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
@@ -1313,12 +1313,17 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e);
13131313
// intersect in nested union environment, similar to subtype_ccheck
13141314
static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int depth)
13151315
{
1316-
jl_value_t *res;
1316+
// band-aid for #30335
1317+
if (x == (jl_value_t*)jl_any_type && !jl_is_typevar(y))
1318+
return y;
1319+
if (y == (jl_value_t*)jl_any_type && !jl_is_typevar(x))
1320+
return x;
1321+
13171322
int savedepth = e->invdepth;
13181323
jl_unionstate_t oldRunions = e->Runions;
13191324
e->invdepth = depth;
13201325

1321-
res = intersect_all(x, y, e);
1326+
jl_value_t *res = intersect_all(x, y, e);
13221327

13231328
e->Runions = oldRunions;
13241329
e->invdepth = savedepth;
@@ -1446,6 +1451,8 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
14461451
return (jl_value_t*)b;
14471452
}
14481453
else if (bb->constraintkind == 2) {
1454+
// TODO: removing this case fixes many test_brokens in test/subtype.jl
1455+
// but breaks other tests.
14491456
if (!subtype_in_env(a, bb->ub, e))
14501457
return jl_bottom_type;
14511458
jl_value_t *lb = simple_join(bb->lb, a);
@@ -1604,6 +1611,10 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
16041611
// you can construct `T{x} where x` even if T's parameter is actually
16051612
// limited. in that case we might get an invalid instantiation here.
16061613
res = jl_substitute_var(res, vb->var, varval);
1614+
// simplify chains of UnionAlls where bounds become equal
1615+
while (jl_is_unionall(res) && obviously_egal(((jl_unionall_t*)res)->var->lb,
1616+
((jl_unionall_t*)res)->var->ub))
1617+
res = jl_instantiate_unionall((jl_unionall_t*)res, ((jl_unionall_t*)res)->var->lb);
16071618
}
16081619
JL_CATCH {
16091620
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},Int} where LT1<:R1 where R1<:Tuple{Int} where LT<:Int where R<:Tuple{Int},
1413+
U2 = Union{Tuple{LT,R,Int} where LT<:Int where R<:Tuple{Int}, Tuple{LT,R,Int} where LT<:R where R<:Tuple{Int}},
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)