Skip to content

Commit

Permalink
Fix jl_obvious_subtype with INT vararg constraint
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Apr 12, 2019
1 parent 5ce94d8 commit d0d01c0
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
8 changes: 8 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,14 @@ STATIC_INLINE jl_value_t *jl_unwrap_vararg(jl_value_t *v) JL_NOTSAFEPOINT
return jl_tparam0(jl_unwrap_unionall(v));
}

STATIC_INLINE size_t jl_vararg_length(jl_value_t *v) JL_NOTSAFEPOINT
{
assert(jl_is_vararg_type(v));
jl_value_t *len = jl_tparam1(jl_unwrap_unionall(v));
assert(jl_is_long(len));
return jl_unbox_long(len);
}

STATIC_INLINE jl_vararg_kind_t jl_vararg_kind(jl_value_t *v) JL_NOTSAFEPOINT
{
if (!jl_is_vararg_type(v))
Expand Down
25 changes: 19 additions & 6 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -1295,24 +1295,37 @@ JL_DLLEXPORT int jl_obvious_subtype(jl_value_t *x, jl_value_t *y, int *subtype)
return 1;
}
int i, npx = jl_nparams(x), npy = jl_nparams(y);
int vx = 0, vy = 0;
jl_vararg_kind_t vx = JL_VARARG_NONE;
jl_value_t *vxt = NULL;
int vy = 0;
int vnpx = npx;
if (istuple) {
vx = npx > 0 && jl_is_vararg_type(jl_tparam(x, npx - 1));
if (npx > 0) {
jl_value_t *xva = jl_tparam(x, npx - 1);
vx = jl_vararg_kind(xva);
if (vx != JL_VARARG_NONE) {
vxt = jl_unwrap_vararg(xva);
vnpx -= 1;
if (vx == JL_VARARG_INT)
vnpx += jl_vararg_length(xva);
}
}
vy = npy > 0 && jl_is_vararg_type(jl_tparam(y, npy - 1));
}
if (npx != npy || vx || vy) {
if (!vy) {
if (npx != npy || vx != JL_VARARG_NONE || vy) {
if ((vx == JL_VARARG_NONE || vx == JL_VARARG_UNBOUND) && !vy) {
*subtype = 0;
return 1;
}
if (npx - vx < npy - vy) {
if ((vx == JL_VARARG_NONE || vx == JL_VARARG_INT) && vnpx < npy - vy) {
*subtype = 0;
return 1; // number of fixed parameters in x could be fewer than in y
}
// TODO: Can do better here for the JL_VARARG_INT case.
uncertain = 1;
}
for (i = 0; i < npy - vy; i++) {
jl_value_t *a = jl_tparam(x, i);
jl_value_t *a = i >= (npx - (vx == JL_VARARG_NONE ? 0 : 1)) ? vxt : jl_tparam(x, i);
jl_value_t *b = jl_tparam(y, i);
if (iscov || jl_is_typevar(b)) {
if (jl_obvious_subtype(a, b, subtype)) {
Expand Down
3 changes: 3 additions & 0 deletions test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1471,3 +1471,6 @@ CovType{T} = Union{AbstractArray{T,2},
@testintersect(Pair{<:Any, <:AbstractMatrix},
Pair{T, <:CovType{T}} where T<:AbstractFloat,
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})

0 comments on commit d0d01c0

Please sign in to comment.