Skip to content

Commit f9b6264

Browse files
committed
Optimization for non-union invariant parameter.
1 parent 0d1c461 commit f9b6264

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/subtype.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,11 +1437,44 @@ static int _local_forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t
14371437
return sub;
14381438
}
14391439

1440+
static int obviously_nounion(jl_value_t *x, jl_stenv_t *e, jl_typeenv_t *log) JL_NOTSAFEPOINT
1441+
{
1442+
if (x == NULL || x == (jl_value_t*)jl_any_type || x == jl_bottom_type)
1443+
return 1;
1444+
if (jl_is_unionall(x))
1445+
return obviously_nounion(((jl_unionall_t *)x)->body, e, log);
1446+
if (jl_is_datatype(x)) {
1447+
jl_datatype_t *xd = (jl_datatype_t *)x;
1448+
for (int i = 0; i < jl_nparams(xd); i++) {
1449+
jl_value_t *param = jl_tparam(xd, i);
1450+
if (jl_is_vararg(param))
1451+
param = jl_unwrap_vararg(param);
1452+
if (!obviously_nounion(param, e, log))
1453+
return 0;
1454+
}
1455+
return 1;
1456+
}
1457+
if (!jl_is_typevar(x))
1458+
return 0;
1459+
jl_typeenv_t *t = log;
1460+
while (t != NULL) {
1461+
if (x == (jl_value_t *)t->var)
1462+
return 0;
1463+
t = t->prev;
1464+
}
1465+
jl_typeenv_t newlog = { (jl_tvar_t*)x, NULL, log };
1466+
jl_varbinding_t *xb = lookup(e, (jl_tvar_t *)x);
1467+
return obviously_nounion(xb ? xb->lb : ((jl_tvar_t *)x)->lb, e, &newlog) &&
1468+
obviously_nounion(xb ? xb->ub : ((jl_tvar_t *)x)->ub, e, &newlog);
1469+
}
1470+
14401471
static int local_forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param, int limit_slow)
14411472
{
14421473
int16_t oldRmore = e->Runions.more;
14431474
int sub;
1444-
if (pick_union_decision(e, 1) == 0) {
1475+
if (obviously_nounion(y, e, NULL))
1476+
sub = _local_forall_exists_subtype(x, y, e, param);
1477+
else if (pick_union_decision(e, 1) == 0) {
14451478
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions);
14461479
e->Lunions.used = e->Runions.used = 0;
14471480
e->Lunions.depth = e->Runions.depth = 0;

test/subtype.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,3 +2436,7 @@ let A = Tuple{Type{T}, T} where T,
24362436
C = Tuple{Type{MyType47877{W, V} where V<:Union{MyAbstract47877{W}, Base.BitInteger}}, MyType47877{W, V} where V<:Union{MyAbstract47877{W}, Base.BitInteger}} where W<:Base.BitInteger
24372437
@test typeintersect(B, A) == C
24382438
end
2439+
2440+
let a = (isodd(i) ? Pair{Char, String} : Pair{String, String} for i in 1:2000)
2441+
@test Tuple{Type{Pair{Union{Char, String}, String}}, a...} <: Tuple{Type{Pair{K, V}}, Vararg{Pair{A, B} where B where A}} where V where K
2442+
end

0 commit comments

Comments
 (0)