Skip to content

Commit 3a1a626

Browse files
committed
Force deep widening if widen2ub == 1
Otherwise `type->ub` might still contains TypeVar that should be nondiagonal.
1 parent 8ed70c6 commit 3a1a626

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

src/subtype.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4376,18 +4376,21 @@ static void check_diagonal(jl_value_t *t, jl_varbinding_t *troot, int param)
43764376

43774377
static jl_value_t *insert_nondiagonal(jl_value_t *type, jl_varbinding_t *troot, int widen2ub)
43784378
{
4379-
// we must replace each covariant occurrence of newvar with a different newvar2<:newvar (diagonal rule)
43804379
if (jl_is_typevar(type)) {
4380+
int concretekind = widen2ub > 1 ? 0 : 1;
43814381
jl_varbinding_t *v = troot;
43824382
for (; v != NULL; v = v->prev) {
4383-
if (v->concrete && v->var == (jl_tvar_t *)type)
4383+
if (v->occurs_inv == 0 &&
4384+
v->occurs_cov > concretekind &&
4385+
v->var == (jl_tvar_t *)type)
43844386
break;
43854387
}
43864388
if (v != NULL) {
43874389
if (widen2ub) {
4388-
type = ((jl_tvar_t *)type)->ub;
4390+
type = insert_nondiagonal(((jl_tvar_t *)type)->ub, troot, 2);
43894391
}
43904392
else {
4393+
// we must replace each covariant occurrence of newvar with a different newvar2<:newvar (diagonal rule)
43914394
if (v->innervars == NULL)
43924395
v->innervars = jl_alloc_array_1d(jl_array_any_type, 0);
43934396
jl_value_t *newvar = NULL, *lb = v->var->lb, *ub = (jl_value_t *)v->var;
@@ -4443,7 +4446,8 @@ static jl_value_t *insert_nondiagonal(jl_value_t *type, jl_varbinding_t *troot,
44434446
// As for Vararg we'd better widen it's var to ub as otherwise they are still diagonal
44444447
jl_value_t *t = jl_unwrap_vararg(type);
44454448
jl_value_t *n = jl_unwrap_vararg_num(type);
4446-
widen2ub = !(n && jl_is_long(n)) || jl_unbox_long(n) > 1;
4449+
if (widen2ub == 0)
4450+
widen2ub = !(n && jl_is_long(n)) || jl_unbox_long(n) > 1;
44474451
jl_value_t *newt;
44484452
JL_GC_PUSH2(&newt, &n);
44494453
newt = insert_nondiagonal(t, troot, widen2ub);
@@ -4475,10 +4479,8 @@ static jl_value_t *insert_nondiagonal(jl_value_t *type, jl_varbinding_t *troot,
44754479
static jl_value_t *_widen_diagonal(jl_value_t *t, jl_varbinding_t *troot) {
44764480
check_diagonal(t, troot, 0);
44774481
int any_concrete = 0;
4478-
for (jl_varbinding_t *v = troot; v != NULL; v = v->prev) {
4479-
v->concrete = v->occurs_cov > 1 && v->occurs_inv == 0;
4480-
any_concrete |= v->concrete;
4481-
}
4482+
for (jl_varbinding_t *v = troot; v != NULL; v = v->prev)
4483+
any_concrete |= v->occurs_cov > 1 && v->occurs_inv == 0;
44824484
if (!any_concrete)
44834485
return t; // no diagonal
44844486
return insert_nondiagonal(t, troot, 0);

test/core.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8065,5 +8065,7 @@ let widen_diagonal(x::UnionAll) = Base.rewrap_unionall(Base.widen_diagonal(Base.
80658065
check_widen_diagonal(x, y) = !<:(x, y) && x <: widen_diagonal(y)
80668066
@test Tuple{Int,Float64} <: widen_diagonal(NTuple)
80678067
@test Tuple{Int,Float64} <: widen_diagonal(Tuple{T,T} where {T})
8068+
@test Tuple{Real,Int,Float64} <: widen_diagonal(Tuple{S,Vararg{T}} where {S, T<:S})
8069+
@test Tuple{Int,Int,Float64,Float64} <: widen_diagonal(Tuple{S,S,Vararg{T}} where {S, T<:S})
80688070
@test Union{Tuple{T}, Tuple{T,Int}} where {T} == widen_diagonal(Union{Tuple{T}, Tuple{T,Int}} where {T})
80698071
end

0 commit comments

Comments
 (0)