Skip to content

Commit bcda552

Browse files
committed
fix #39698, bad Vararg typevar bounds due to intersection
caused by #39623
1 parent 7853ddd commit bcda552

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

src/subtype.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2510,6 +2510,7 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
25102510
else if (!(oldval && jl_is_typevar(oldval) && jl_is_long(varval)))
25112511
e->envout[e->envidx] = fix_inferred_var_bound(vb->var, varval);
25122512
}
2513+
vb->var = newvar;
25132514

25142515
JL_GC_POP();
25152516
return res;
@@ -2587,21 +2588,35 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_
25872588
res = intersect_unionall_(t, u, e, R, param, &vb);
25882589
if (res != jl_bottom_type) {
25892590
if (vb.concrete || vb.occurs_inv>1 || u->var->lb != jl_bottom_type || (vb.occurs_inv && vb.occurs_cov)) {
2591+
jl_value_t *u2 = (jl_value_t*)u;
2592+
JL_GC_PUSH1(&u2);
2593+
// This step maintains variable bounds from the previous intersect_unionall_ call.
2594+
// So, if we needed to rename the variable, make sure `u` uses the same variable
2595+
// so we know it actually refers to the same type in the environment.
2596+
// This is a bit of a hack to fix #39698.
2597+
if (vb.var != u->var) {
2598+
u2 = jl_instantiate_unionall(u, (jl_value_t*)vb.var);
2599+
u2 = (jl_value_t*)jl_type_unionall(vb.var, u2);
2600+
assert(jl_is_unionall(u2));
2601+
}
25902602
restore_env(e, NULL, &se);
25912603
vb.occurs_cov = vb.occurs_inv = 0;
25922604
vb.constraintkind = 3;
2593-
res = intersect_unionall_(t, u, e, R, param, &vb);
2605+
res = intersect_unionall_(t, (jl_unionall_t*)u2, e, R, param, &vb);
2606+
JL_GC_POP();
25942607
}
25952608
else if (vb.occurs_cov) {
25962609
save_env(e, &save2, &se2);
25972610
restore_env(e, save, &se);
25982611
vb.occurs_cov = vb.occurs_inv = 0;
2612+
vb.var = u->var;
25992613
vb.lb = u->var->lb; vb.ub = u->var->ub;
26002614
vb.constraintkind = 1;
26012615
res2 = intersect_unionall_(t, u, e, R, param, &vb);
26022616
if (res2 == jl_bottom_type) {
26032617
restore_env(e, save, &se);
26042618
vb.occurs_cov = vb.occurs_inv = 0;
2619+
vb.var = u->var;
26052620
vb.lb = u->var->lb; vb.ub = u->var->ub;
26062621
vb.constraintkind = 2;
26072622
res2 = intersect_unionall_(t, u, e, R, param, &vb);

test/subtype.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,3 +1885,12 @@ let A = Tuple{Type{<:Union{Number, T}}, Ref{T}} where T,
18851885
@test A == B
18861886
@test A <: B
18871887
end
1888+
1889+
# issue #39698
1890+
let T = Type{T} where T<:(AbstractArray{I}) where I<:(Base.IteratorsMD.CartesianIndex),
1891+
S = Type{S} where S<:(Base.IteratorsMD.CartesianIndices{A, B} where B<:Tuple{Vararg{Any, A}} where A)
1892+
I = typeintersect(T, S)
1893+
@test I <: T
1894+
@test I <: S
1895+
@test_broken I == typeintersect(S, T)
1896+
end

0 commit comments

Comments
 (0)