From aa58f67e4a9bd9d27b4395733966a39b0153597a Mon Sep 17 00:00:00 2001 From: N5N3 <2642243996@qq.com> Date: Thu, 24 Oct 2024 07:32:33 +0800 Subject: [PATCH] typeintersect: more fastpath to skip intersect under circular env (#56304) fix #56040 (cherry picked from commit 53ffe5630cff5d974722ec197c6f53b907ffd457) --- src/subtype.c | 9 +++++++-- test/subtype.jl | 9 +++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 0b1e987e5ee1b..24c4d74440282 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -2392,8 +2392,10 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, return y; if (y == (jl_value_t*)jl_any_type && !jl_is_typevar(x)) return x; - // band-aid for #46736 - if (obviously_egal(x, y)) + // band-aid for #46736 #56040 + if (obviously_in_union(x, y)) + return y; + if (obviously_in_union(y, x)) return x; jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions); @@ -2407,6 +2409,9 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t *e, int8_t R, int param) { + // band-aid for #56040 + if (!jl_is_uniontype(x) && obviously_in_union((jl_value_t *)u, x)) + return x; if (param == 2 || (!jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u))) { jl_value_t *a=NULL, *b=NULL; JL_GC_PUSH2(&a, &b); diff --git a/test/subtype.jl b/test/subtype.jl index f0b81bd72d7d7..93deda2a9929a 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -2641,3 +2641,12 @@ let S = Tuple{Val, Val{T}} where {T}, R = Tuple{Val{Val{T}}, Val{T}} where {T}, @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NamedTuple{(:a),B}}}, S{NTuple{2,Int}}, R{NTuple{2,Int}}) @testintersect(Tuple{Val{A}, A} where {B, A<:Union{Val{B}, NamedTuple{B,Tuple{Int,Int}}}}, S{(:a,:a)}, R{(:a,:a)}) end + +#issue 56040 +let S = Dict{V,V} where {V}, + T = Dict{Ref{Union{Set{A2}, Set{A3}, A3}}, Ref{Union{Set{A3}, Set{A2}, Set{A1}, Set{A4}, A4}}} where {A1, A2<:Set{A1}, A3<:Union{Set{A1}, Set{A2}}, A4<:Union{Set{A2}, Set{A1}, Set{A3}}}, + A = Dict{Ref{Set{Union{}}}, Ref{Set{Union{}}}} + @testintersect(S, T, !Union{}) + @test A <: typeintersect(S, T) + @test A <: typeintersect(T, S) +end