Skip to content

Commit 6ae113f

Browse files
committed
Optimization for non-union invariant parameter.
1 parent e2ebb14 commit 6ae113f

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/subtype.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,11 +1423,42 @@ static int is_definite_length_tuple_type(jl_value_t *x)
14231423

14241424
static int _forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param, int *count, int *noRmore);
14251425

1426+
static int obviously_nounion(jl_value_t *x, jl_stenv_t *e, jl_typeenv_t *log) JL_NOTSAFEPOINT
1427+
{
1428+
if (x == NULL || x == (jl_value_t*)jl_any_type || x == jl_bottom_type)
1429+
return 1;
1430+
if (jl_is_unionall(x))
1431+
return obviously_nounion(((jl_unionall_t *)x)->body, e, log);
1432+
if (jl_is_datatype(x)) {
1433+
jl_datatype_t *xd = (jl_datatype_t *)x;
1434+
for (int i = 0; i < jl_nparams(xd); i++) {
1435+
jl_value_t *param = jl_tparam(xd, i);
1436+
if (jl_is_vararg(param))
1437+
param = jl_unwrap_vararg(param);
1438+
if (!obviously_nounion(param, e, log))
1439+
return 0;
1440+
}
1441+
return 1;
1442+
}
1443+
if (!jl_is_typevar(x))
1444+
return 0;
1445+
jl_typeenv_t *t = log;
1446+
while (t != NULL) {
1447+
if (x == (jl_value_t *)t->var)
1448+
return 0;
1449+
t = t->prev;
1450+
}
1451+
jl_typeenv_t newlog = { (jl_tvar_t*)x, NULL, log };
1452+
jl_varbinding_t *xb = lookup(e, (jl_tvar_t *)x);
1453+
return obviously_nounion(xb ? xb->lb : ((jl_tvar_t *)x)->lb, e, &newlog) &&
1454+
obviously_nounion(xb ? xb->ub : ((jl_tvar_t *)x)->ub, e, &newlog);
1455+
}
1456+
14261457
static int local_forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param, int limit_slow)
14271458
{
14281459
int16_t oldRmore = e->Runions.more;
14291460
int sub;
1430-
if (pick_union_decision(e, 1) == 0) {
1461+
if (!obviously_nounion(y, e, NULL) && pick_union_decision(e, 1) == 0) {
14311462
jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions);
14321463
e->Lunions.used = e->Runions.used = 0;
14331464
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)