Skip to content

Commit

Permalink
fix #39698, bad Vararg typevar bounds due to intersection
Browse files Browse the repository at this point in the history
caused by #39623
  • Loading branch information
JeffBezanson committed Feb 18, 2021
1 parent 7853ddd commit bcda552
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2510,6 +2510,7 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
else if (!(oldval && jl_is_typevar(oldval) && jl_is_long(varval)))
e->envout[e->envidx] = fix_inferred_var_bound(vb->var, varval);
}
vb->var = newvar;

JL_GC_POP();
return res;
Expand Down Expand Up @@ -2587,21 +2588,35 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_
res = intersect_unionall_(t, u, e, R, param, &vb);
if (res != jl_bottom_type) {
if (vb.concrete || vb.occurs_inv>1 || u->var->lb != jl_bottom_type || (vb.occurs_inv && vb.occurs_cov)) {
jl_value_t *u2 = (jl_value_t*)u;
JL_GC_PUSH1(&u2);
// This step maintains variable bounds from the previous intersect_unionall_ call.
// So, if we needed to rename the variable, make sure `u` uses the same variable
// so we know it actually refers to the same type in the environment.
// This is a bit of a hack to fix #39698.
if (vb.var != u->var) {
u2 = jl_instantiate_unionall(u, (jl_value_t*)vb.var);
u2 = (jl_value_t*)jl_type_unionall(vb.var, u2);
assert(jl_is_unionall(u2));
}
restore_env(e, NULL, &se);
vb.occurs_cov = vb.occurs_inv = 0;
vb.constraintkind = 3;
res = intersect_unionall_(t, u, e, R, param, &vb);
res = intersect_unionall_(t, (jl_unionall_t*)u2, e, R, param, &vb);
JL_GC_POP();
}
else if (vb.occurs_cov) {
save_env(e, &save2, &se2);
restore_env(e, save, &se);
vb.occurs_cov = vb.occurs_inv = 0;
vb.var = u->var;
vb.lb = u->var->lb; vb.ub = u->var->ub;
vb.constraintkind = 1;
res2 = intersect_unionall_(t, u, e, R, param, &vb);
if (res2 == jl_bottom_type) {
restore_env(e, save, &se);
vb.occurs_cov = vb.occurs_inv = 0;
vb.var = u->var;
vb.lb = u->var->lb; vb.ub = u->var->ub;
vb.constraintkind = 2;
res2 = intersect_unionall_(t, u, e, R, param, &vb);
Expand Down
9 changes: 9 additions & 0 deletions test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1885,3 +1885,12 @@ let A = Tuple{Type{<:Union{Number, T}}, Ref{T}} where T,
@test A == B
@test A <: B
end

# issue #39698
let T = Type{T} where T<:(AbstractArray{I}) where I<:(Base.IteratorsMD.CartesianIndex),
S = Type{S} where S<:(Base.IteratorsMD.CartesianIndices{A, B} where B<:Tuple{Vararg{Any, A}} where A)
I = typeintersect(T, S)
@test I <: T
@test I <: S
@test_broken I == typeintersect(S, T)
end

0 comments on commit bcda552

Please sign in to comment.