Skip to content

Commit

Permalink
Fix a vararg-related non-transitivity in subtyping
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Apr 12, 2019
1 parent d0d01c0 commit d14696e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
27 changes: 18 additions & 9 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,11 +796,16 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
if (lx == 0 && ly == 0)
return 1;
size_t i=0, j=0;
int vx=0, vy=0, vvx = (lx > 0 && jl_is_vararg_type(jl_tparam(xd, lx-1)));
int vx=0, vy=0;
jl_vararg_kind_t vvx = JL_VARARG_NONE;
if (lx > 0)
vvx = jl_vararg_kind(jl_tparam(xd, lx-1));
int vvy = (ly > 0 && jl_is_vararg_type(jl_tparam(yd, ly-1)));
if (vvx) {
if ((vvy && ly > lx) || (!vvy && ly < lx-1))
return 0;
if (vvx != JL_VARARG_NONE) {
if (vvx == JL_VARARG_UNBOUND) {
if (!vvy && ly < lx - 1)
return 0;
}
}
else if ((vvy && ly > lx+1) || (!vvy && lx != ly)) {
return 0;
Expand All @@ -809,14 +814,16 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
jl_value_t *lastx=NULL, *lasty=NULL;
while (i < lx) {
jl_value_t *xi = jl_tparam(xd, i);
if (i == lx-1 && vvx) vx = 1;
if (i == lx-1 && vvx) {
vx += 1;
}
jl_value_t *yi = NULL;
if (j < ly) {
yi = jl_tparam(yd, j);
if (j == ly-1 && vvy) vy = 1;
if (j == ly-1 && vvy) vy += 1;
}
if (vx && !vy) {
if (!check_vararg_length(xi, ly+1-lx, e))
if (!check_vararg_length(xi, ly-lx+(vvy ? 0 : 1), e))
return 0;
jl_tvar_t *p1=NULL, *p2=NULL;
xi = unwrap_2_unionall(xi, &p1, &p2);
Expand Down Expand Up @@ -858,9 +865,11 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
jl_value_t *xl = jl_tparam1(xi);
if (jl_is_typevar(xl)) {
jl_varbinding_t *xlv = lookup(e, (jl_tvar_t*)xl);
if (xlv && jl_is_long(xlv->lb) && jl_unbox_long(xlv->lb) == 0)
break;
if (xlv)
xl = xlv->lb;
}
if (jl_is_long(xl) && jl_unbox_long(xl) + 1 == vx)
return 1;
}
if (jl_is_datatype(yi)) {
jl_value_t *yl = jl_tparam1(yi);
Expand Down
9 changes: 8 additions & 1 deletion test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1473,4 +1473,11 @@ CovType{T} = Union{AbstractArray{T,2},
Pair{T,S} where S<:AbstractArray{T,2} where T<:AbstractFloat)

# Various nasty varargs
@assert issub_strict(Tuple{Int, Tuple{T}, Vararg{T, 3}} where T<:Int, Tuple{Int, Any, Any, Any, Integer})
let T1 = Tuple{Int, Tuple{T}, Vararg{T, 3}} where T <: Int,
T2 = Tuple{Int, Any, Any, Any, Integer},
T3 = Tuple{Int, Any, Any, Any, Integer, Vararg{Integer, N} where N}

@test issub_strict(T1, T2)
@test issub_strict(T2, T3)
@test issub_strict(T1, T3)
end

0 comments on commit d14696e

Please sign in to comment.