From 48fc5ff203b0b9dc2645b81e5234d9c79df07897 Mon Sep 17 00:00:00 2001 From: N5N3 <2642243996@qq.com> Date: Sat, 28 Jan 2023 23:19:33 +0800 Subject: [PATCH] `exists_equal` tuning. Make sure we don't forget the bound in `env`. And this makes `subtype` slightly faster by reducing heavy re-subtyping. But of course we will consume more Runion stack with this change. --- src/subtype.c | 17 ++++++++++++++--- test/subtype.jl | 8 ++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 9e83d48bc49b01..f97313ca057d9e 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -1461,6 +1461,7 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) (is_definite_length_tuple_type(x) && is_indefinite_length_tuple_type(y))) return 0; + jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions); if ((jl_is_uniontype(x) && jl_is_uniontype(y))) { // For 2 unions, first try a more efficient greedy algorithm that compares the unions @@ -1472,7 +1473,6 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) // } // Optimization - jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions); int16_t old2Rmore = e->Runions.more; if (pick_union_decision(e, 1) == 0) { int16_t oldRmore = e->Runions.more; @@ -1506,7 +1506,6 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) if ((!jl_has_free_typevars(x) || !jl_has_free_typevars(y))) sub = local_forall_exists_subtype(x, y, e, 2); else { - jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions); e->Lunions.used = 0; while (1) { e->Lunions.more = 0; @@ -1518,7 +1517,19 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) pop_unionstate(&e->Lunions, &oldLunions); } - return sub && subtype(y, x, e, 0); + if (sub) { + e->Lunions.used = 0; + while (1) { + e->Lunions.more = 0; + e->Lunions.depth = 0; + sub = subtype(y, x, e, 0); + if (!sub || !next_union_state(e, 0)) + break; + } + pop_unionstate(&e->Lunions, &oldLunions); + } + + return sub; } static int exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, jl_value_t *saved, jl_savedenv_t *se, int param) diff --git a/test/subtype.jl b/test/subtype.jl index ffe794323e2b8f..97fb9952c9c887 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1480,10 +1480,10 @@ f24521(::Type{T}, ::Type{T}) where {T} = T @test f24521(Tuple{Vararg{Int64}}, Tuple{Vararg{Int64,N}} where N) == Tuple{Vararg{Int64,N}} where N # issue #26654 -@test_broken !(Ref{Union{Int64, Ref{Number}}} <: Ref{Union{Ref{T}, T}} where T) -@test_broken !(Ref{Union{Int64, Val{Number}}} <: Ref{Union{Val{T}, T}} where T) -@test_broken !(Ref{Union{Ref{Number}, Int64}} <: Ref{Union{Ref{T}, T}} where T) -@test_broken !(Ref{Union{Val{Number}, Int64}} <: Ref{Union{Val{T}, T}} where T) +@test !(Ref{Union{Int64, Ref{Number}}} <: Ref{Union{Ref{T}, T}} where T) +@test !(Ref{Union{Int64, Val{Number}}} <: Ref{Union{Val{T}, T}} where T) +@test !(Ref{Union{Ref{Number}, Int64}} <: Ref{Union{Ref{T}, T}} where T) +@test !(Ref{Union{Val{Number}, Int64}} <: Ref{Union{Val{T}, T}} where T) # issue #26180 @test !(Ref{Union{Ref{Int64}, Ref{Number}}} <: Ref{Ref{T}} where T)