Skip to content

Commit f11a702

Browse files
committed
typeintersect: fix triangular vars handling outside constructor (#58018)
also add more fast path.
1 parent e2ca0c1 commit f11a702

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/subtype.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,7 +1354,7 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
13541354
x = pick_union_element(x, e, 0);
13551355
}
13561356
if (jl_is_uniontype(y)) {
1357-
if (x == ((jl_uniontype_t*)y)->a || x == ((jl_uniontype_t*)y)->b)
1357+
if (obviously_in_union(y, x))
13581358
return 1;
13591359
if (jl_is_unionall(x))
13601360
return subtype_unionall(y, (jl_unionall_t*)x, e, 0, param);
@@ -2484,9 +2484,6 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e,
24842484

24852485
static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t *e, int8_t R, int param)
24862486
{
2487-
// band-aid for #56040
2488-
if (!jl_is_uniontype(x) && obviously_in_union((jl_value_t *)u, x))
2489-
return x;
24902487
if (param == 2 || (!jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u))) {
24912488
jl_value_t *a=NULL, *b=NULL;
24922489
JL_GC_PUSH2(&a, &b);
@@ -2616,7 +2613,7 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten
26162613
// subtype, treating all vars as existential
26172614
static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t *e)
26182615
{
2619-
if (x == jl_bottom_type || y == (jl_value_t*)jl_any_type)
2616+
if (x == jl_bottom_type || y == (jl_value_t*)jl_any_type || obviously_in_union(y, x))
26202617
return 1;
26212618
int8_t *rs = (int8_t*)alloca(current_env_length(e));
26222619
jl_varbinding_t *v = e->vars;
@@ -2739,7 +2736,7 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int
27392736
jl_value_t *ub = R ? intersect_aside(a, bb->ub, e, bb->depth0) : intersect_aside(bb->ub, a, e, bb->depth0);
27402737
if (ub == jl_bottom_type)
27412738
return jl_bottom_type;
2742-
if (bb->constraintkind == 1 || e->triangular) {
2739+
if (bb->constraintkind == 1 || (e->triangular && param == 1)) {
27432740
if (e->triangular && check_unsat_bound(ub, b, e))
27442741
return jl_bottom_type;
27452742
set_bound(&bb->ub, ub, b, e);
@@ -3914,12 +3911,14 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa
39143911
if (jl_subtype(y, x)) return y;
39153912
}
39163913
if (jl_is_uniontype(x)) {
3917-
if (y == ((jl_uniontype_t*)x)->a || y == ((jl_uniontype_t*)x)->b)
3914+
if (obviously_in_union(x, y))
39183915
return y;
3916+
if (jl_is_uniontype(y) && obviously_in_union(y, x))
3917+
return x;
39193918
return intersect_union(y, (jl_uniontype_t*)x, e, 0, param);
39203919
}
39213920
if (jl_is_uniontype(y)) {
3922-
if (x == ((jl_uniontype_t*)y)->a || x == ((jl_uniontype_t*)y)->b)
3921+
if (obviously_in_union(y, x))
39233922
return x;
39243923
if (jl_is_unionall(x) && (jl_has_free_typevars(x) || jl_has_free_typevars(y)))
39253924
return intersect_unionall(y, (jl_unionall_t*)x, e, 0, param);

test/subtype.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,8 +2085,7 @@ let A = Tuple{Any, Type{Ref{_A}} where _A},
20852085
I = typeintersect(A, B)
20862086
@test I != Union{}
20872087
@test Tuple{Type{Ref{Integer}}, Type{Ref{Integer}}} <: I
2088-
# TODO: this intersection result seems too wide (I == B) ?
2089-
@test_broken !<:(Tuple{Type{Int}, Type{Int}}, I)
2088+
@test !<:(Tuple{Type{Int}, Type{Int}}, I)
20902089
end
20912090

20922091
@testintersect(Tuple{Type{T}, T} where T<:(Tuple{Vararg{_A, _B}} where _B where _A),
@@ -2706,3 +2705,15 @@ end
27062705
Pair{N, T} where {N,NTuple{N,Int}<:T<:Tuple{Int,Vararg{Int}}},
27072706
!Union{}
27082707
)
2708+
2709+
#issue 57852
2710+
@testintersect(
2711+
Tuple{Type{T}, Type{<:F}, Type{<:F}} where {T, F<:Union{String, T}},
2712+
Tuple{Type{Complex{T}} where T, Type{Complex{T}} where T, Type{String}},
2713+
Tuple{Type{Complex{T}}, Type{Complex{T}}, Type{String}} where T
2714+
)
2715+
@testintersect(
2716+
Tuple{Type{T}, Type{<:Union{F, Nothing}}, Type{<:Union{F, Nothing}}} where {T, F<:Union{String, T}},
2717+
Tuple{Type{Complex{T}} where T, Type{Complex{T}} where T, Type{String}},
2718+
Tuple{Type{Complex{T}}, Type{Complex{T}}, Type{String}} where T
2719+
)

0 commit comments

Comments
 (0)