Skip to content

Commit

Permalink
WIP: fix #47658, state stack overflow on unions containing typevars
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Jan 11, 2023
1 parent 1e5fdb2 commit fe02b62
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
16 changes: 16 additions & 0 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,19 @@ static int subtype_tuple(jl_datatype_t *xd, jl_datatype_t *yd, jl_stenv_t *e, in
return ans;
}

static int equal_unions(jl_uniontype_t *x, jl_uniontype_t *y, jl_stenv_t *e)
{
jl_value_t *saved=NULL; jl_savedenv_t se;
JL_GC_PUSH1(&saved);
save_env(e, &saved, &se);
int eq = forall_exists_equal(x->a, y->a, e) && forall_exists_equal(x->b, y->b, e);
if (!eq)
restore_env(e, saved, &se);
free_env(&se);
JL_GC_POP();
return eq;
}

// `param` means we are currently looking at a parameter of a type constructor
// (as opposed to being outside any type constructor, or comparing variable bounds).
// this is used to record the positions where type variables occur for the
Expand Down Expand Up @@ -1432,6 +1445,9 @@ 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;

if (jl_is_uniontype(x) && jl_is_uniontype(y) && equal_unions(x, y, e))
return 1;

jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions);
e->Lunions.used = 0;
int sub;
Expand Down
20 changes: 18 additions & 2 deletions test/subtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2352,6 +2352,16 @@ let S = Tuple{Type{T1}, T1, Val{T1}} where T1<:(Val{S1} where S1<:Val),
@test_broken I2 <: T
end

@test only(intersection_env(Val{Union{Val{Val{T}} where {T},Int}}, Val{Union{T,Int}} where T)[2]) === Val{Val{T}} where {T}

# issue 47654
Vec47654{T} = Union{AbstractVector{T}, AbstractVector{Union{T,Nothing}}}
struct Wrapper47654{T, V<:Vec47654{T}}
v::V
end
abstract type P47654{A} end
@test Wrapper47654{P47654, Vector{Union{P47654,Nothing}}} <: Wrapper47654

@testset "known subtype/intersect issue" begin
#issue 45874
# Causes a hang due to jl_critical_error calling back into malloc...
Expand All @@ -2362,7 +2372,7 @@ end
# end

#issue 44395
@test_broken typeintersect(
@test typeintersect(
Tuple{Type{T}, T} where {T <: Vector{Union{T, R}} where {R<:Real, T<:Real}},
Tuple{Type{Vector{Union{T, R}}}, Matrix{Union{T, R}}} where {R<:Real, T<:Real},
) === Union{}
Expand All @@ -2389,7 +2399,7 @@ end
@test_broken typeintersect(Tuple{Type{Tuple{T,Val{T}}}, Val{T}} where T, Tuple{Type{Tuple{Val{T},T}}, Val{T}} where T) <: Any

# issue 24333
@test_broken (Type{Union{Ref,Cvoid}} <: Type{Union{T,Cvoid}} where T)
@test (Type{Union{Ref,Cvoid}} <: Type{Union{T,Cvoid}} where T)

# issue 22123
t1 = Ref{Ref{Ref{Union{Int64, T}}} where T}
Expand All @@ -2400,6 +2410,12 @@ end
@test_broken (Tuple{T1,T1} where T1<:(Val{T2} where T2)) <: (Tuple{Val{S},Val{S}} where S)
end

# issue #47658
let T = Ref{NTuple{8, Ref{Union{Int, P}}}} where P,
S = Ref{NTuple{8, Ref{Union{Int, P}}}} where P
@test T <: Union{Int, S}
end

@test !(Tuple{Any, Any, Any} <: Tuple{Any, Vararg{T}} where T)

abstract type MyAbstract47877{C}; end
Expand Down

0 comments on commit fe02b62

Please sign in to comment.